Tadle

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

The protocol does not work with fee-on transfer tokens as expected

Summary

According to Readme and the comments in the codebase, the protocol is expected to work with Erc20 tokens. However TokenManager.sol does not properly support tokens that implement a fee on transfer.

Vulnerability Details

The withdraw function is intended to handle both native and erc20 tokens.

function withdraw(
address _tokenAddress,
TokenBalanceType _tokenBalanceType
) external whenNotPaused {
uint256 claimAbleAmount = userTokenBalanceMap[_msgSender()][
_tokenAddress
][_tokenBalanceType];
if (claimAbleAmount == 0) {
return;
}
address capitalPoolAddr = tadleFactory.relatedContracts(
RelatedContractLibraries.CAPITAL_POOL
);
if (_tokenAddress == wrappedNativeToken) {
....
//SKIPPED
...
} else {
/**
* @dev token is ERC20 token
* @dev transfer from capital pool to msg sender
*/
_safe_transfer_from(
_tokenAddress,
capitalPoolAddr,
_msgSender(),
claimAbleAmount //@audit-issue this will not work for FoTs
);
}
emit Withdraw(
_msgSender(),
_tokenAddress,
_tokenBalanceType,
claimAbleAmount
);
}

The logic in the withdraw function assumes that claimAbleAmount will be transferred to the user by _safe_transfer_from. However, if the token is a fee-on transfer token, the actual amount received by the user will be less due to the fee deducted.

NOTE: Also tillIn function has the similar issue. In this function, a call is made to _transfer, which records the balances of both the sender (_from) and the recipient (_to) before the transfer. It then checks whether the balances of sender and recipient have changed by exactly the amount specified.

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

Due to the checks here , the function will be reverted, which means whenever FoT token is involved user deposits will not work as intended.

Impact

The protocol will be incompatible with any FoT tokens and users will be affected accordingly

Tools Used

Manual review, Vs Code

Recommendations

I would recommend checking balance of msg.sender for the _tokenAddress before and after the transfer so that the actual amount received (by user or capital pool) after the fee is applied.

Updates

Lead Judging Commences

0xnevi Lead Judge over 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.

Give us feedback!