The protocol could lose funds due to no support for fee-on-transfer/deflationary tokens.
Vulnerability Detail
The _processTopup function in HardendedTopupProxy.sol will receive tokens from the user and will either bridge the tokens directly if the token is the cardTopupToken or swap the tokens to the cardTopupToken using the executeSwapDirect function, then bridge the tokens to L1 ETH mainnet. When the token sent to the contract is the same as cardTopupToken then the function uses the amount input variable given to _processTopup instead of the actual amount received after the token transfer. If a fee-on-transfer token is used as the cardTopupToken instead of USDC then the actual amount received by the contract will be less than the amount given as input.
This issue does not seem to occur when the token is not the same as cardTopupToken since the executeSwapDirect function checks for actual amount received and returns only the amount received from the swap. The actual amount received by the protocol will be emitted with the CardTopup event.
Impact
The protocol will lose funds because the user will receive more tokens than they should when the topup is processed on the backend infrastructure..
if (_token == cardTopupToken) {
// beneficiary is msg.sender (perform static check)
IERC20Upgradeable(_token).safeTransferFrom(_beneficiary, address(this), _amount);
uint256 feeAmount = _amount.mul(topupFee).div(1e18);
// bridge from _beneficiary to card L1 relay
_bridgeAssetDirect(_amount.sub(feeAmount), _bridgeType, _bridgeTxData);
emit CardTopup(_beneficiary, _token, _amount, _amount.sub(feeAmount), _receiverHash);
return;
}
Tool used
Manual Review
Recommendation
Check the actual amount received from transfers by recording the balance before and after a transfer then taking the difference as the actual amount received.
dipp
medium
Fee-on-transfer/deflationary tokens not supported
Summary
The protocol could lose funds due to no support for fee-on-transfer/deflationary tokens.
Vulnerability Detail
The
_processTopup
function inHardendedTopupProxy.sol
will receive tokens from the user and will either bridge the tokens directly if the token is the cardTopupToken or swap the tokens to the cardTopupToken using theexecuteSwapDirect
function, then bridge the tokens to L1 ETH mainnet. When the token sent to the contract is the same ascardTopupToken
then the function uses the amount input variable given to_processTopup
instead of the actual amount received after the token transfer. If a fee-on-transfer token is used as thecardTopupToken
instead of USDC then the actual amount received by the contract will be less than the amount given as input.This issue does not seem to occur when the token is not the same as
cardTopupToken
since theexecuteSwapDirect
function checks for actual amount received and returns only the amount received from the swap. The actual amount received by the protocol will be emitted with the CardTopup event.Impact
The protocol will lose funds because the user will receive more tokens than they should when the topup is processed on the backend infrastructure..
Code Snippet
HardenedTopupProxy.sol:_processTopup#L315-L326
Tool used
Manual Review
Recommendation
Check the actual amount received from transfers by recording the balance before and after a transfer then taking the difference as the actual amount received.
Duplicate of #39