code-423n4 / 2021-04-maple-findings

0 stars 0 forks source link

Any valid liquidator can arbitrage from the loan contract to earn collateral assets by exploiting the maximum slippage when defaulting a loan. #111

Closed code423n4 closed 3 years ago

code423n4 commented 3 years ago

Handle

shw

Vulnerability details

Impact

This vulnerability is an arbitrage attack that any valid liquidator (person who has at least 20% of loan equity) can launch with a high possibility of success. The loan contract can lose up to globals.maxSwapSlippage percent (which is 10% in the default settings) of collateralAsset when defaulting the loan. The liquidator, in the end, profits from the loan contract after swapping liquidityAsset back to collateralAsset.

The convertERC20 function in MapleTreasury has a similar swapping logic and is also vulnerable to this arbitrage attack. However, it requires a governor to call the function, and so it is less exploitable.

Proof of Concept

In LoanLib.sol#104, the minAmount is calculated through the price of ChainLink oracles and thus does not affected by the reserves in the Uniswap pools. The step for a liquidator to arbitrage is as follows:

  1. The liquidator first swaps a large amount of collateralAsset to liquidityAsset via the pre-determined Uniswap path.
  2. The liquidator then triggers the loan default, forces the loan contract to liquidate the borrower's collateralAsset via Uniswap at a relatively bad price. However, the price slippage is still less than the maximum swap slippage allowed, so the swap is successful.
  3. The liquidator swaps liquidityAsset back to collateralAsset to profit, earning some collateralAsset that should belong to the loan contract.

Notice that steps 1. to 3. are done in a single transaction to prevent others from interrupting. This arbitrage is similar to a "sandwitch attack" except that the trades are all made within one transaction. The liquidator should also carefully calculate the amount of collateralAsset to swap at Step 1 to not exceed the price slippage specified by globals.maxSwapSlippage.

Tools Used

None

Recommended Mitigation Steps

Restrict the triggerDefault function for pool delegates only, or lower down the maxSwapSlippage (e.g., to 3%) to make such arbitrage unprofitable.

lucas-manuel commented 3 years ago

This is not a bug, we are fully aware of this. This is why the triggerDefault function is permissioned, and only Pools can fund Loans. This means that only Pool Delegates can trigger liquidations, and they are considered trusted actors.

Arachnid commented 3 years ago

To clarify, since I had to check myself - LoanLib.canTriggerDefault checks that the caller has enough tokens to qualify as a liquidator, and only pools can have these tokens.