Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fee-on-transfer tokens support must be forbidden or allowed with amount update #18

Closed
code423n4 opened this issue May 12, 2022 · 3 comments
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working duplicate This issue or pull request already exists sponsor disputed Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue

Comments

@code423n4
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//contracts/AuraBalRewardPool.sol#L126
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//contracts/AuraBalRewardPool.sol#L146
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//contracts/AuraBalRewardPool.sol#L162
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//contracts/AuraBalRewardPool.sol#L185
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//contracts/AuraBalRewardPool.sol#L198
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//contracts/AuraClaimZap.sol#L202
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//contracts/AuraClaimZap.sol#L223
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//contracts/AuraLocker.sol#L234
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//contracts/AuraLocker.sol#L251
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//contracts/AuraLocker.sol#L314
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//contracts/AuraLocker.sol#L367
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//contracts/AuraLocker.sol#L448
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//contracts/AuraLocker.sol#L456
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//contracts/AuraLocker.sol#L826
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//contracts/AuraLocker.sol#L857
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289/contracts/AuraMerkleDrop.sol#L100
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289/contracts/AuraMerkleDrop.sol#L138
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289/contracts/AuraMerkleDrop.sol#L153
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289/contracts/AuraStakingProxy.sol#L162
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289/contracts/AuraStakingProxy.sol#L190
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289/contracts/AuraStakingProxy.sol#L212
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289/contracts/AuraVestedEscrow.sol#L108
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289/contracts/AuraVestedEscrow.sol#L123
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289/contracts/AuraVestedEscrow.sol#L189
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289/contracts/BalLiquidityProvider.sol#L91
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289/contracts/CrvDepositorWrapper.sol#L79
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289/contracts/ExtraRewardsDistributor.sol#L93
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289/contracts/ExtraRewardsDistributor.sol#L154
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/ArbitartorVault.sol#L57
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/BaseRewardPool.sol#L179
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/BaseRewardPool.sol#L198
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/BaseRewardPool.sol#L237
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/BaseRewardPool.sol#L289
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/BaseRewardPool.sol#L315
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/BaseRewardPool4626.sol#L56
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/Booster.sol#L404
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/Booster.sol#L476
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/Booster.sol#L606
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/Booster.sol#L613
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/Booster.sol#L617
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/Booster.sol#L621
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/Booster.sol#L625
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/Booster.sol#L658
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/ConvexMasterChef.sol#L221
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/ConvexMasterChef.sol#L250
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/ConvexMasterChef.sol#L286
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/ConvexMasterChef.sol#L302
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/ConvexMasterChef.sol#L304
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/CrvDepositor.sol#L114
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/CrvDepositor.sol#L173
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/CrvDepositor.sol#L182
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/ExtraRewardStashV3.sol#L209
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/ExtraRewardStashV3.sol#L215
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/RewardHook.sol#L49
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/VirtualBalanceRewardPool.sol#L198
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/VirtualBalanceRewardPool.sol#L208
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/VoterProxy.sol#L213
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/VoterProxy.sol#L311
https://github.com/code-423n4/2022-05-aura/blob/085f573756b132b2a5992c5aa5d7b907cd11c289//convex-platform/contracts/contracts/VoterProxy.sol#L337

Vulnerability details

Impact

Every time transferFrom or transfer function in ERC20 standard is called there is a possibility that underlying smart contract did not transfer the exact amount entered.
It is required to find out contract balance increase/decrease after the transfer to allow fee-on-transfer tokens or forbid non-standard tokens.
This pattern also prevents from re-entrancy attack vector.

Proof of Concept

POC (re-entrancy for fee-on-transfer tokens):

  1. Contract calls transfer from contractA 100 tokens to current contract
  2. Current contract thinks it received 100 tokens
  3. It updates internal balance sheet +100 tokens
  4. While actually contract received only 90 tokens
  5. That breaks whole math for given token
  6. Now imagine some fake token which does not send anything
    Attacker could run re-entrancy and boosting deposits in the storage while transferring nothing.
    At the end drain tokenOut (if it is DEX) or withdraw something else based on large deposit.

Tools Used

Recommended Mitigation Steps

There are several possible scenarios to prevent that.

  1. Check how much contract balance is increased/decreased after every transfer (costs more gas)
  2. Make a separate contract that checks if the token has fee-on-transfer and store bool value depending on the result.
    If there is fee-on-transfer you can throw a require not allowing to use such token in the system while still saving lots of gas checking it only once.
    Or if you still want to allow fee-on-transfer tokens, amount variable must be updated to the balance difference after and before transfer.

Recommended example code:

mapping(IERC20 => bool) doesThisContractHaveFeeOnTransfer;
enum FeeOnTransferStatuses{ NOT_INITIALIZED, HAS_FEE_ON_TRANSFER, DOES_NOT_HAVE_FEE_ON_TRANSFER }
error FeeOnTransferTokensAreForbidden();
...
function deposit(IERC20 token, address from, uint256 amount) public {

    // reverting for fee-on-transfer tokens
    if (doesThisContractHaveFeeOnTransfer[token] == FeeOnTransferStatuses.HAS_FEE_ON_TRANSFER) {
        revert FeeOnTransferTokensAreForbidden();
    }

    // NOT_INITIALIZED is the default value == 0
    if (doesThisContractHaveFeeOnTransfer[token] == FeeOnTransferStatuses.NOT_INITIALIZED) {
        uint256 balanceBefore = token.balanceOf(address(this)); // remembering asset balance before the transfer
        token.safeTransferFrom(from, address(this), amount);
        uint256 balanceAfter = token.balanceOf(address(this));

        // making sure exactly amount was transferred
        if (balanceAfter != balanceBefore + amount) {            
            revert FeeOnTransferTokensAreForbidden();
        }

        // IMPORTANT! if you allow fee-on-transfer tokens make sure to update amount with the actual balance increase/decrease
        // or make sure balanceAfter - balanceBefore == amount using require
        // amount = balanceAfter - balanceBefore; // commented because we skip fee-on-transfer tokens above

        doesThisContractHaveFeeOnTransfer[token] = FeeOnTransferStatuses.DOES_NOT_HAVE_FEE_ON_TRANSFER; // making sure to not enter this if clause anymore for given token
    } else {
        // token does not have fee-on-transfer here
        token.safeTransferFrom(from, address(this), amount);
    }

    // no re-entrancy vector attack below here 
    // amount is set to exactly how much contract balance was increased

    registerDeposit(from, amount); 
}

@code423n4 code423n4 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels May 12, 2022
code423n4 added a commit that referenced this issue May 12, 2022
@0xMaharishi 0xMaharishi added invalid This doesn't seem right sponsor disputed Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue labels May 25, 2022
@0xMaharishi
Copy link

Tokens used in Aura do not have transfer fees

@dmvt
Copy link
Collaborator

dmvt commented Jun 20, 2022

There are several cases in the code reported where the token in question comes from an external (non-admin, non-protocol) source. One of these is the addReward functionality (ExtraRewards). This would indeed cause an accounting issue and allow a potential malicious actor to send rewards which cause distribution to fail due to lack of funds. Just because you don't plan to use fee on transfer tokens, does not mean they will not be used. This should be protected against in the scenarios where it could cause an issue.

That said, this clearly requires external factors and relies on hypothetical attack motivation that seems unlikely to me. Additionally, the warden just threw every transfer line into the report, making this report very hard to parse. I think it should be included as a medium risk, but most of the lines above are actually invalid.

@dmvt dmvt added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value and removed invalid This doesn't seem right 3 (High Risk) Assets can be stolen/lost/compromised directly labels Jun 20, 2022
@dmvt
Copy link
Collaborator

dmvt commented Jul 8, 2022

Duplicate of #176

@dmvt dmvt marked this as a duplicate of #176 Jul 8, 2022
@dmvt dmvt closed this as completed Jul 8, 2022
@dmvt dmvt added the duplicate This issue or pull request already exists label Jul 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working duplicate This issue or pull request already exists sponsor disputed Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue
Projects
None yet
Development

No branches or pull requests

3 participants