Skip to content

Latest commit

 

History

History
68 lines (50 loc) · 3 KB

File metadata and controls

68 lines (50 loc) · 3 KB

Itchy Slate Rat

Medium

Fee-on-transfer tokens are not being accounted for in ERC20VariableIncentive.

Summary

In the claim function, the code assumes that the full claimAmount specified will be received by the claimTarget. However, for fee-on-transfer tokens, the actual amount received will be less than the amount sent. This discrepancy is not accounted for, leading to an overestimation of the totalClaimed amount.

Vulnerability Detail

As stated in the README the protocol does expect interact with all weird ERC20s including USDT. 
Looking at the `claim` function, fee-on-transfer tokens are clearly not being accounted for.
function claim(address claimTarget, bytes calldata data_) external override onlyOwner returns (bool) {
        BoostClaimData memory boostClaimData = abi.decode(data_, (BoostClaimData));
        uint256 signedAmount = abi.decode(boostClaimData.incentiveData, (uint256));
        uint256 claimAmount;
        if (!_isClaimable(claimTarget)) revert NotClaimable();

        if (reward == 0) {
            claimAmount = signedAmount;
        } else {
            // NOTE: this is assuming that the signed scalar is in ETH decimal format
            claimAmount = reward * signedAmount / 1e18;
        }

        if (totalClaimed + claimAmount > limit) revert ClaimFailed();

        totalClaimed += claimAmount; // < @audit
        asset.safeTransfer(claimTarget, claimAmount);

        emit Claimed(claimTarget, abi.encodePacked(asset, claimTarget, claimAmount));
        return true;
    }

This issue is also prevalent in the clawback function.

function clawback(bytes calldata data_) external override onlyOwner returns (bool) {
       ClawbackPayload memory claim_ = abi.decode(data_, (ClawbackPayload));
       (uint256 amount) = abi.decode(claim_.data, (uint256));

       limit -= amount;  // < @audit

       // Transfer the tokens back to the intended recipient
       asset.safeTransfer(claim_.target, amount);
       emit Claimed(claim_.target, abi.encodePacked(asset, claim_.target, amount));

       return true;
   }

As it can be seen in both cases when fee-on-transfer tokens are used the totalClaimed and limit amounts will be updated incorrectly.

Impact

Incorrect values of limit and totalClaimed cause _isClaimable to return incorrect value since it uses the comparison "totalClaimed < limit" thus leading to DoS to the legitimate claimants.

Code Snippet

https://github.com/sherlock-audit/2024-06-boost-aa-wallet/blob/78930f2ed6570f30e356b5529bd4bcbe5194eb8b/boost-protocol/packages/evm/contracts/incentives/ERC20VariableIncentive.sol#L98

https://github.com/sherlock-audit/2024-06-boost-aa-wallet/blob/78930f2ed6570f30e356b5529bd4bcbe5194eb8b/boost-protocol/packages/evm/contracts/incentives/ERC20VariableIncentive.sol#L62

Tool used

Manual Review

Recommendation

Implement a balance check before and after the transfer. Then use the differences in these balances to update the limit and totalClaimed in their respective functions.