Token-0x

First Flight #54
Beginner FriendlyDeFi
100 EXP
Submission Details
Impact: medium
Likelihood: high

Race Condition in approve/transfer-from methods

Author Revealed upon completion

Root + Impact

Description

  • The approve function is vulnerable to the classic ERC20 race condition attack. When changing an existing allowance from a non-zero value to another non-zero value, a malicious spender can observe the approval transaction in the mempool and front-run it to spend the old allowance, then spend the new allowance after it's set, effectively spending both amounts.

Likelihood:

  • Attack sequence:

    1. Alice approves Bob for 100 tokens

    2. Alice decides to increase approval to 200 tokens

    3. Alice sends approve(Bob, 200) transaction

    4. Bob sees the transaction in mempool

    5. Bob front-runs with transferFrom(Alice, Bob, 100) with higher gas

    6. Bob's transaction executes first, spending 100 tokens

    7. Alice's approval transaction executes, setting allowance to 200

    8. Bob calls transferFrom(Alice, Bob, 200) again

    9. Bob has now transferred 300 tokens instead of intended 200

Impact:

  • Users attempting to change existing allowances can have more tokens spent than intended. For example, changing approval from 100 to 200 tokens could result in 300 tokens being spent if the spender front-runs the transaction.

Recommended Mitigation

+ add this code
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = msg.sender;
uint256 currentAllowance = allowance(owner, spender);
_approve(owner, spender, currentAllowance + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = msg.sender;
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
_approve(owner, spender, currentAllowance - subtractedValue);
return true;
}

Support

FAQs

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

Give us feedback!