# The protocol does not compatible with token such as USDT because of the Approval Face Protection

AaveV3LeverageModule approves USDT for repay without zeroing first, so second and later deleverage repay calls revert on approval-race-protected tokens.

- Payout: Contest reward
- Severity: medium
- Program: Index
- Credited: 0x007
- Disclosed: 2023-05-11
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-05-Index-judging/issues/314
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-05-Index%3AM-7
- Tags: domain:web3 impact:dos kind:contest platform:sherlock sev:medium tech:evm tech:solidity technique:source-review vuln:dos

**Target:** AaveV3LeverageModule._repayBorrow / SetToken.invokeApprove
**Root cause:** _repayBorrow calls invokeApprove for the full notional repay quantity, but Aave only pulls the actual debt amount, leaving a residual allowance; the next approve on a token like USDT that requires zeroing allowance first reverts.
**Steps:**
1. Deleverage a SetToken holding USDT debt via AaveV3LeverageModule.delever.
2. _repayBorrow approves lendingPool for notionalQuantity (e.g. 20000 USDT).
3. Aave repays only paybackAmount (e.g. 1000 USDT), leaving 19000 USDT allowance.
4. Second deleverage calls invokeApprove again with non-zero current allowance; USDT reverts.
5. Fix: invokeApprove(asset, pool, 0) before the real approve.
**How found:** Code-reading of _repayBorrow against Aave's BorrowLogic paybackAmount logic, noticing approve amount exceeds actual pulled amount, then cross-referencing weird-erc20 approval race protections.
**Insight:** When a module approves a notional amount but the downstream protocol only pulls the actual debt, residual allowance accumulates; any token with approve-race protection (USDT) will brick repeat flows unless allowance is zeroed first.
