Skip to content

Latest commit

 

History

History
32 lines (24 loc) · 2.88 KB

062.md

File metadata and controls

32 lines (24 loc) · 2.88 KB

Orbiting Sangria Porpoise

Medium

Liquidator may end up receiving no seizeTokens and lose all repayAmount

Summary

During liquidation the protocol calculates the amount of cTokens to seize or seizeTokens like here. There is however

  • no check throughout the liquidation flow to verify if seizeTokens > 0.
    • Note that seizeTokens = 0 is possible because the calculation rounds down in favour of the borrower, not the liquidator here and here.
  • no slippage control param (for example, minAmountExpected) which the liquidator can specify while calling the liquidate functions.

This can result in the liquidator ending up paying repayAmount and reducing the borrower's debt but not receiving anything in return.

Description

Imagine the following:

  1. Numa per cNuma = 2e8 (as per current rates observable in tests)
  2. rEth per Numa = 1_000_000e18 (Numa has appreciated considerably in future)
  3. Bob has borrowed 0.18e18 rEth. This is equivalent to 18e10 Numa which turns out to be 900 cNuma
  4. Alice wants to liquidate Bob's unhealthy debt and calls liquidateBadDebt() with _percentagePosition1000 as 1. This denotes 0.1% of debt to be liquidated. Note that this works similarly in a regular non-bad debt (just shortfall) situation too - the calls to the other liquidate functions need a repayAmount param instead of a percentage param, based on which a ratio is calculated and seizeTokens are calculated ( See inside liquidateCalculateSeizeTokens() ).
  5. rEth amount equal to 0.18e15 is pulled from Alice's account to commence liquidation
  6. In return she gets: seizeTokens = 1 * 900 / 1000 = 0.
  7. No further checks revert due to this and the liquidation flow concludes.

Note that such a situation can happen inadvertently during periods of high volatility too. Alice may have calculated correctly prior to sending her tx so that she receives non-zero seizeTokens but by the time the tx executes, price movement could well rob her of any returns.

Impact

Liquidator can end up paying repayAmount and reducing the borrower's debt but not receiving anything in return.

Recommendation

  • Add verification for seizeTokens > 0.
  • Add a slippage control param (for example, minAmountExpected) which a liquidator can specify while calling the liquidate functions.