Open sherlock-admin opened 1 year ago
Looks reasonable to add a preceding zero approval here
_setToken.invokeApprove(address(_asset), address(_lendingPool), 0);
Valid medium
Still having some final discussion internally over wether to fix this or explicitly list USDT as an incompatible token.
Fixed in: https://github.com/IndexCoop/index-protocol/pull/22
Specifically in the following commit by preceding any approve transaction with a 0 approval: https://github.com/IndexCoop/index-protocol/pull/22/commits/dae4d65ae8a95f9044b4c2edccaa394dbff451f3
@ckoopmann some of the duplicates such as #39 and #129 are about the AmmModule
As mentioned by @bizzyvinci this same change should be made to the AMM module as well
Fixes look good and now always approve to 0 first
ShadowForce
medium
The protocol does not compatible with token such as USDT because of the Approval Face Protection
Summary
The protocol does not compatible with token such as USDT because of the Approval Face Protection
Vulnerability Detail
the protocol is intended to interact with any ERC20 token and USDT is a common one
when doing the deleverage
https://github.com/IndexCoop/index-protocol/blob/86be7ee76d9a7e4f7e93acfc533216ebef791c89/contracts/protocol/modules/v1/AaveV3LeverageModule.sol#L313
first, we construct the deleverInfo
then we withdraw from the lending pool, execute trade and repay the borrow token
this is calling _repayBorrow
the trade received (quantity - the protocol fee) is used to repay the debt
but the required debt to be required is the (borrowed amount + the interest rate)
suppose the only debt that needs to be repayed is 1000 USDT
trade received (quantity - the protocol) fee is 20000 USDT
only 1000 USDT is used to repay the debt
because when repaying, the paybackAmount is only the debt amount
https://github.com/aave/aave-v3-core/blob/29ff9b9f89af7cd8255231bc5faf26c3ce0fb7ce/contracts/protocol/libraries/logic/BorrowLogic.sol#L204
then when burning the variable debt token
https://github.com/aave/aave-v3-core/blob/29ff9b9f89af7cd8255231bc5faf26c3ce0fb7ce/contracts/protocol/libraries/logic/BorrowLogic.sol#L224
only the "payback amount", which is 1000 USDT is transferred to pay the debt,
the excessive leftover amount is (20000 USDT - 1000 USDT) = 19000 USDT
but if we lookback into the repayBack function
the approved amount is 20000 USDT, but only 1000 USDT approval limit is used, we have 19000 USDT approval limit left
according to
https://github.com/d-xo/weird-erc20#approval-race-protections
USDT is such token that subject to approval race condition, without approving 0 first, the second approve after first repay will revert
Impact
second and following repay borrow will revert if the ERC20 token is subject to approval race condition
Code Snippet
https://github.com/IndexCoop/index-protocol/blob/86be7ee76d9a7e4f7e93acfc533216ebef791c89/contracts/protocol/modules/v1/AaveV3LeverageModule.sol#L313
Tool used
Manual Review
Recommendation
Approval 0 first