Tadle

Tadle
DeFi
30,000 USDC
View results
Submission Details
Severity: medium
Valid

Current Accounting Incompatible With Some ERC20s

Summary

The Tadle system is expected to be compatible with ETH, WETH, and any token following the ERC20 standard. However, the current implementation is incompatible with certain types of ERC20 tokens, such as Fee-on-transfer tokens, Rebase tokens, stETH, and tokens that return false instead of reverting on failure. This incompatibility can lead to accounting issues, unexpected transaction failures, and potential denial-of-service (DoS) on the system.

Vulnerability Details

According to the documentation, Tadle should support the following token types:

Tokens:
- ETH
- WETH
- ERC20 (any token that follows the ERC20 standard)

However, the system fails to account for certain types of tokens, even if they technically adhere to the ERC20 standard. The following issues arise:

Case 1: Fee-on-transfer Tokens

Fee-on-transfer tokens deduct a certain fee during transfers. The current implementation of TokenManager::_transfer checks the toBalanceBef and toBalanceAft as follows:

if (toBalanceAft != toBalanceBef + _amount) {
revert TransferFailed();
}

This logic fails with Fee-on-transfer tokens because the amount transferred to the recipient will be less than _amount due to the fee. As a result, the transaction will revert with a TransferFailed error, making the system incompatible with these tokens.

Case 2: Rebase Tokens

Rebase tokens automatically adjust the balance of users over time. In such cases, the deposited amount may not directly correspond to the withdrawal share, leading to discrepancies in accounting. This could result in funds being locked in the contract or users losing access to their full balance.

Case 3: stETH

It is known for stETH that is has 1 wei corner case where a discrepancy of 1 wei may occur during transfers. The current implementation of TokenManager::_transfer strictly checks the sender’s balance before and after the transfer:TokenManager::_transfer:

if (fromBalanceAft != fromBalanceBef - _amount) {
revert TransferFailed();
}

When this corner case occurs, the transaction will fail, making the system incompatible with stETH.

Case 4: Tokens that return False instead of reverting.
Some tokens, such as ZRX and EURS, do not revert on failure but instead return false. The current implementation in Rescue::_safe_transfer and Rescue::_safe_transfer_from which is used in TokenManager does not account for this behavior:

(bool success, ) = token.call(
abi.encodeWithSelector(TRANSFER_FROM_SELECTOR, from, to, amount)
);
if (!success) {
revert TransferFailed();
}

If the token returns false instead of reverting, the function will not revert as expected, leading to unintended consequences such as incorrect token transfers or accounting errors.

Impact

The issues identified can cause significant problems, including:

  1. Incompatibility with Fee-on-Transfer Tokens: Transactions involving these tokens will fail, making the system unusable for users holding such tokens.

  2. Accounting Issues with Rebase Tokens: Users may lose access to their full balances due to incorrect accounting, leading to potential loss of funds.

  3. Failure with stETH: The 1 wei corner case can cause transactions to fail, preventing users from transferring or withdrawing stETH.

  4. Unintended Consequences with Non-Reverting Tokens: Tokens that return false instead of reverting can cause the system to behave unexpectedly, leading to incorrect token transfers or failed operations.

Tools Used

Manual

Recommendations

  1. Revise the Design of Accounting: The system should be updated to handle the unique behaviors of Fee-on-transfer tokens, Rebase tokens, stETH, and tokens that return false on failure. This may involve implementing specific logic to handle these cases.

  2. Update Documentation: If supporting these tokens is not feasible, the documentation should be updated to clearly state the limitations and specify which types of tokens are supported.

Updates

Lead Judging Commences

0xnevi Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-TokenManager-FOT-Rebasing

Valid medium, there are disruptions to the ability to take market actions. The following functions will be disrupted without the possibiliy of reaching settlement, since the respective offers cannot be created/listed regardless of mode when transferring collateral token required to the CapitalPool contract or when refunding token from user to capital pool during relisting. So withdrawal is not an issue - `createOffer()` - reverts [here](https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/PreMarkets.sol#L96-L102) - `listOffer()` - reverts [here](https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/PreMarkets.sol#L355-L362) - `relistOffer()` - reverts [here](https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/PreMarkets.sol#L515-L521) - `createTaker()` - reverts [here](https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/PreMarkets.sol#L831-L836) I believe medium severity is appropriate although the likelihood is high and impact is medium (only some level of disruption i.e. FOT tokens not supported and no funds at risk)

Support

FAQs

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