20,000 USDC
View results
Submission Details
Severity: high
Valid

Tokens with a fee-on-transfer mechanism or rebase tokens may break the protocol

Summary

Tokens with a fee-on-transfer mechanism or rebase tokens may break the protocol

Vulnerability Details

The ERC20 logic in the contracts is incompatible with tokens that have a fee-on-transfer mechanism, such as PAXG and USDT (with the fee-on-transfer currently switched off).

The implementation of the deposit and withdraw functions in the Staking contract incorrectly handles the fee, resulting in discrepancies in token balances.

To illustrate the issue, a scenario is presented below:

  1. Bob deposits 100 tokens.

  2. Alice deposits 100 tokens.

  3. Bob withdraws 100 tokens.

When Bob deposits 100 tokens, the contract will save the amount as 100 tokens, but the actual transferred amount will be amount - fee (95 tokens).

function deposit(uint _amount) external {
TKN.transferFrom(msg.sender, address(this), _amount);
updateFor(msg.sender);
balances[msg.sender] += _amount;
}

Later, when Bob withdraws, he is able to withdraw the full amount - 100 tokens (Bob will receive only 95 tokens due to the fee).

function withdraw(uint _amount) external {
updateFor(msg.sender);
balances[msg.sender] -= _amount;
TKN.transfer(msg.sender, _amount);
}

This will lead to a loss for Alice when she withdraws her tokens from the contract, as the remaining token amount will be smaller.

Impact

The vulnerability causes incorrect functionality in the protocol when dealing with tokens that have a fee-on-transfer mechanism or rebase tokens. It results in a discrepancy between the expected and actual token balances within the contract. When the last person tries to transfer tokens out of the contract, it may lead to revert and potential financial losses for users.

Tools Used

Manual review

Recommendations

To address this vulnerability, the following recommendations are proposed:

  1. Implement a balance check before executing transferFrom to the contract and verify the balance again after the transfer. Use the difference between the two balances as the newly added balance.
    Apply a nonReentrant modifier to prevent manipulation by ERC777 tokens.

  2. Alternatively, if supporting tokens with a fee-on-transfer mechanism or rebase tokens is not feasible, it is advised to clearly document and announce that such tokens are not supported by the contract.

Support

FAQs

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