Tadle

Tadle
DeFiFoundry
27,750 USDC
View results
Submission Details
Severity: low
Invalid

Withdraw Amount Larger Than Allowance Will Be Reverted

Summary

The TokenManager contract has a vulnerability where the Withdrawal of tokens will revert if the amount exceeds the approved allowance and the allowance is not reset to zero. This can disrupt protocol activities and affect many users.

Vulnerability Details

The root cause of the vulnerability is that the contract requires the allowance to be zero before extending it.

  • Found in src/core/TokenManager.sol at Line 245

@>: The condition to extend the allowance strictly waits for the allowance to be set to 0x0 before invoking the next approve() call. This creates a vulnerability where the withdrawal amount exceeds the approved amount, but a new approval cannot be initiated. As a result, the next _safe_transfer_from call at Line 250 will revert due to insufficient allowances.

233: function _transfer(
...
244: _from == _capitalPoolAddr &&
245:@> IERC20(_token).allowance(_from, address(this)) == 0x0
246: ) {
...
250:@> _safe_transfer_from(_token, _from, _to, _amount);
262: }

Impact

The likelihood of this occurring could be ranging in Med if protocol's activities are high, causing allowance to drain fast. The impact is High because it may lead to frequent reverts and disruption of protocol activities, potentially affecting many users.

Attack Scenario

Let us walk through the issue with the following scenario:

  1. After sometime of operation, the TokenManager's WETH allowances to draw funds from CapitalPool is reduced to a dust value of 1 wei.

  2. Alice tries to withdraw 1 WETH, but due to the strict condition that the WETH allowance must be 0x0, the new approval at line 247 is not called, causing a revert of Insuffient Allowances when TokenManager trying to withdraw 1 WETH from CapitalPool.

  3. The issue persists across many users like Alice until someone who:

    • Figures out the coding problem (which may take some time).

    • Has a claimAmountAmount from userTokenBalanceMap of 1 wei (less likely).

    • Finally, deliberately calls withdraw() to clear out the allowance to 0x0.

From these reasons, the impact could be critical due to the high number of users affected and the rarity of recovery.

Tools Used

Manual Review

Recommendations

Instead of waiting till 0x0 allowance reached, try to check the remaining allowances against the transfer amount _amount to get the necessary extension in-time.

- IERC20(_token).allowance(_from, address(this)) == 0x0
+ IERC20(_token).allowance(_from, address(this)) < _amount
Updates

Lead Judging Commences

0xnevi Lead Judge
about 1 year ago
0xnevi Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Appeal created

0xpep7 Submitter
about 1 year ago
0xnevi Lead Judge
about 1 year ago
0xnevi Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

[invalid] finding-CapitalPool-USDT-approve-zero-first

I believe this is invalid, - For weird ERC20s with front-running approval protection such as UDST (only known instance so far), max approval is likely only required to be invoked once, considering the supply cap of such tokens. (USDT supply is at 53.8 billion (53.8e9 * 1e9, so this is 100% sufficient) - If approvals are insufficient, a new proxy for tadle market can always be deployed via the TadleFactory contract and migrated

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.