Tadle

Tadle
DeFi
30,000 USDC
View results
Submission Details
Severity: low
Invalid

Improper Handling of Native Token in `tillIn` Function

Summary

The tillIn function in TokenManager.sol does not properly handle native tokens (ETH) when the accepted token is not the native token. This can lead to incorrect transfers and potential loss of funds.

Vulnerability Details

Location: TokenManager.sol

Description:

The tillIn function allows users to deposit tokens into the contract. If the token being deposited is not the native token (ETH), the function should not accept ETH along with the call. Currently, the function does not enforce this, allowing users to send ETH even when depositing ERC20 tokens.

Proof of Concept

function tillIn(
address _accountAddress,
address _tokenAddress,
uint256 _amount,
bool _isPointToken
)
external
payable
onlyRelatedContracts(tadleFactory, _msgSender())
onlyInTokenWhiteList(_isPointToken, _tokenAddress)
{
/// @notice return if amount is 0
if (_amount == 0) {
return;
}
address capitalPoolAddr = tadleFactory.relatedContracts(RelatedContractLibraries.CAPITAL_POOL);
if (capitalPoolAddr == address(0x0)) {
revert Errors.ContractIsNotDeployed();
}
if (_tokenAddress == wrappedNativeToken) {
/**
* @dev token is native token
* @notice check msg value
* @dev if msg value is less than _amount, revert
* @dev wrap native token and transfer to capital pool
*/
if (msg.value < _amount) {
revert Errors.NotEnoughMsgValue(msg.value, _amount);
}
IWrappedNativeToken(wrappedNativeToken).deposit{value: _amount}();
_safe_transfer(wrappedNativeToken, capitalPoolAddr, _amount);
} else {
/// @notice token is ERC20 token
_transfer(_tokenAddress, _accountAddress, capitalPoolAddr, _amount, capitalPoolAddr);
}
emit TillIn(_accountAddress, _tokenAddress, _amount, _isPointToken);
}

Root Cause:

The function does not check for the presence of msg.value when the token being deposited is not the native token. This allows users to inadvertently send ETH with their transactions, potentially leading to lost funds.

Impact

This vulnerability can result in users accidentally sending ETH when it is not required, leading to loss of funds and incorrect contract behavior. This mismanagement of funds can disrupt the expected operation of the contract and cause financial losses for users.

Tools Used

  • Manual review

Recommendations

Add a Check for msg.value:
Ensure that msg.value is zero when the token being deposited is not the native token.

function tillIn(
address _accountAddress,
address _tokenAddress,
uint256 _amount,
bool _isPointToken
)
external
payable
onlyRelatedContracts(tadleFactory, _msgSender())
onlyInTokenWhiteList(_isPointToken, _tokenAddress)
{
/// @notice return if amount is 0
if (_amount == 0) {
return;
}
address capitalPoolAddr = tadleFactory.relatedContracts(RelatedContractLibraries.CAPITAL_POOL);
if (capitalPoolAddr == address(0x0)) {
revert Errors.ContractIsNotDeployed();
}
if (_tokenAddress == wrappedNativeToken) {
/**
* @dev token is native token
* @notice check msg value
* @dev if msg value is less than _amount, revert
* @dev wrap native token and transfer to capital pool
*/
if (msg.value < _amount) {
revert Errors.NotEnoughMsgValue(msg.value, _amount);
}
IWrappedNativeToken(wrappedNativeToken).deposit{value: _amount}();
_safe_transfer(wrappedNativeToken, capitalPoolAddr, _amount);
} else {
/// @notice token is ERC20 token
// Ensure no ETH is sent along with the call
require(msg.value == 0, "ETH should not be sent with ERC20 tokens");
_transfer(_tokenAddress, _accountAddress, capitalPoolAddr, _amount, capitalPoolAddr);
}
emit TillIn(_accountAddress, _tokenAddress, _amount, _isPointToken);
}
Updates

Lead Judging Commences

0xnevi Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Known issue
Assigned finding tags:

[invalid] finding-TokenManager-tillin-excess

Invalid, these are by default, invalid based on codehawks [general guidelines](https://docs.codehawks.com/hawks-auditors/how-to-determine-a-finding-validity#findings-that-may-be-invalid). The check implemented is simply a sufficiency check, it is users responsibility to only send an appropriate amount of native tokens where amount == msg.value when native token is intended to be used as collateral (which will subsequently be deposited as wrapped token). All excess ETH can be rescued using the `Rescuable.sol` contract. > Users sending ETH/native tokens > If contracts allow users to send tokens acc111identally.

Support

FAQs

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