Entering markets and borrowing assets increases the gas cost required to perform account equity calculation (Controller.calcAccountEquity
).
This calculation is required for several controller methods:
beforeTransfer
(via_redeemAllowed
)beforeRedeem
(via_redeemAllowed
)beforeBorrow
beforeLiquidateBorrow
This actions correspond to the following iToken methods:
transfer
andtransferFrom
redeem
andredeemUnderlying
borrow
liquidateBorrow
andseize
By manipulating their number of entered markets and borrowed assets, an attacker is able to force these methods to fail as their cost will exceed the block gas limit. Additionally, the cost to enter a market is relatively low, and does not depend on the number of previously-entered markets / previously-borrowed assets. This means that an attacker can borrow until they are at risk of being liquidated, then enter several markets and prevent the liquidation from occuring.
There are a few iToken methods that do not rely on calcAccountEquity
:
mint
repayBorrow
andrepayBorrowBehalf
The below code deploys ~200 iTokens and estimates the gas cost of calcAccountEquity
for a few different numbers of entered markets / borrowed assets. Unfortunately, the test takes some ~7 min to run fully due to the number of tokens that need to be deployed and the time it takes to estimate gas. I've included the important console output below, so you don't need to run the test yourself:
Tester has entered 1 markets
Tester has borrowed in 150 markets
== Entering markets:
calcAccountEquity cost: 3758304
Total collaterals: 2
Total borrows: 150
calcAccountEquity cost: 4106283
Total collaterals: 12
Total borrows: 150
calcAccountEquity cost: 4425929
Total collaterals: 22
Total borrows: 150
calcAccountEquity cost: 4745582
Total collaterals: 32
Total borrows: 150
calcAccountEquity cost: 5100437
Total collaterals: 42
Total borrows: 150
calcAccountEquity cost: 5417564
Total collaterals: 52
Total borrows: 150
calcAccountEquity cost: 5734698
Total collaterals: 62
Total borrows: 150
calcAccountEquity cost: 6079424
Total collaterals: 72
Total borrows: 150
calcAccountEquity cost: 6394033
Total collaterals: 82
Total borrows: 150
calcAccountEquity cost: 6753669
Total collaterals: 92
Total borrows: 150
calcAccountEquity cost: 7063215
Total collaterals: 102
Total borrows: 150
calcAccountEquity cost: 7407641
Total collaterals: 112
Total borrows: 150
calcAccountEquity cost: 7741922
Total collaterals: 122
Total borrows: 150
calcAccountEquity cost: 8066060
Total collaterals: 132
Total borrows: 150
calcAccountEquity cost: 8399702
Total collaterals: 142
Total borrows: 150
calcAccountEquity cost: 8713049
Total collaterals: 152
Total borrows: 150
calcAccountEquity cost: 9044094
Total collaterals: 162
Total borrows: 150
calcAccountEquity cost: 9393851
Total collaterals: 172
Total borrows: 150
1) Estimates gas for calcAccountEquity
0 passing (9m)
1 failing
1) Tester
Estimates gas for calcAccountEquity:
Error: Transaction reverted and Hardhat couldn't infer the reason. Please report this to help us improve Hardhat