Submitted by 0x52
Adversary can maliciously disable cToken collateral to cause loss to rToken during restructuring.
CTokenNonFiatCollateral and CTokenFiatCollateral both use the default refresh behavior presented in FiatCollateral which has the above lines which automatically disables the collateral if the reference price ever decreases. This makes the assumption that cToken exchange rates never decrease but this is an incorrect assumption and can be exploited by an attacker to maliciously disable a cToken being used as collateral.
CToken.sol
The exchange rate can be manipulated by a tiny amount during the redeem process. The focus above is the scenario where the user requests a specific amount of underlying. When calculating the number of cTokens to redeem for a specific amount of underlying it rounds IN FAVOR of the user. This allows the user to redeem more underlying than the exchange rate would otherwise imply. Because the user can redeem slightly more than intended they can create a scenario in which the exchange rate actually drops after they redeem. This is because compound calculates the exchange rate dynamically using the current supply of cTokens and the assets under management.
CToken.sol
The exchangeRate when _totalSupply != 0 is basically:
Using this formula for we can now walk through an example of how this can be exploited
Example:
cTokens always start at a whole token ratio of 50:1 so lets assume this ratio to begin with. Lets use values similar to the current supply of cETH which is ~15M cETH and ~300k ETH. Well start by calculating the current ratio:
Now to exploit the ratio we request to redeem 99e8 redeemAmount which we can use to calculate the amount of tokens we need to burn:
After truncation the amount burned is only 1. Now we can recalculate our ratio:
The ratio has now been slightly decreased. In CTokenFiatCollateral the exchange rate is truncated to 18 dp so:
This results in that the collateral is now disabled. This forces the vault to liquidate their holdings to convert to a backup asset. This will almost certainly incur losses to the protocol that were maliciously inflicted.
The path to exploit is relatively straightforward:
refresh() cToken collateral to store current rate -> Manipulate compound rate via redemption -> refresh() cToken collateral to disable
Since the issue is with the underlying compound contracts, nothing can make the attack impossible but it can be made sufficiently difficult. The simplest deterrent would be to implement a rate error value (i.e. 100) so that the exchange rate has to drop more than that before the token is disabled. The recommended value for this is a bit more complicated to unpack. The amount that the exchange rate changes heavily depends on the number of cTokens minted. The larger the amount the less it changes. Additionally a malicious user can make consecutive redemptions to lower the rate even further. Using an error rate of 1e12 would make it nearly impossible for this to be exploited while still being very sensitive to real (and concerning) changes in exchange rate.
0xean (judge) commented:
tmattimore (Reserve) confirmed
tbrent (Reserve) commented:
tbrent (Reserve) mitigated:
Status: Mitigation confirmed with comments. Full details in reports from HollaDieWaldfee, 0xA5DF, and AkshaySrivastav.
