Tadle

Tadle
DeFiFoundry
27,750 USDC
View results
Submission Details
Severity: medium
Valid

`TokenManager.sol::_transfer` could result in incorrect reverts on Weird ERC20 tokens, leading to failed tranactions or loss of funds

Summary

The _transfer function in the TokenManager.sol contract has a potential vulnerability when interacting with [Weird ERC20 tokens](https://github.com/d-xo/weird-erc20), specifically those that implement transfer fees, burning mechanisms, or other weird behaviors. This issue could cause the function to revert transactions unnecessarily, leading to potential disruptions in the intended operation of the contract and loss of funds.

Vulnerability Details

See TokenManager.sol::_transfer

https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/TokenManager.sol#L233-L262

function _transfer(
address _token,
address _from,
address _to,
uint256 _amount,
address _capitalPoolAddr
) internal {
uint256 fromBalanceBef = IERC20(_token).balanceOf(_from);
uint256 toBalanceBef = IERC20(_token).balanceOf(_to);
if (
_from == _capitalPoolAddr &&
IERC20(_token).allowance(_from, address(this)) == 0x0
) {
ICapitalPool(_capitalPoolAddr).approve(address(this));
}
_safe_transfer_from(_token, _from, _to, _amount);
uint256 fromBalanceAft = IERC20(_token).balanceOf(_from);
uint256 toBalanceAft = IERC20(_token).balanceOf(_to);
if (fromBalanceAft != fromBalanceBef - _amount) {
revert TransferFailed();
}
if (toBalanceAft != toBalanceBef + _amount) {
revert TransferFailed();
}
}

The _transfer function checks the balance of the sender (_from) and receiver (_to) before and after the token transfer, expecting the balances to change exactly by the _amount specified. However, if the token implements non-standard behavior like deducting a fee on transfer or burning a portion of the tokens, these checks will fail, causing the function to revert unnecessarily.

For example, for a token with a 5% transfer fee, a transfer of 100 tokens would result in the receiver getting 95 tokens. The current implementation of _transfer expects the receiver to get the full 100 tokens, so it will incorrectly revert the transaction.

Impact

The erroneous balance checks will cause legitimate transactions to revert, potentially leading to disruptions in the system’s functionality. End-users might experience failed transactions without clear understanding or reason, leading to a loss of funds, and a loss of trust in the system.

Tools Used

Manual Review

Recommendations

Replace the custom _transfer implementation with OpenZeppelin’s safeTransfer and safeTransferFrom functions. These functions are battle-tested and handle edge cases across a wide range of ERC20 implementations.

Updates

Lead Judging Commences

0xnevi Lead Judge about 1 year 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.