Token-0x

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

Allowance Race Condition (Unsafe Approve Overwrite)

Author Revealed upon completion

Root + Impact

Description

  • ERC20 allowances should prevent the classic approval race condition by enforcing:

    newAllowance == 0 || oldAllowance == 0
  • The internal helper directly overwrites allowance without enforcing safe patterns.

function _approveInternal(address owner, address spender, uint256 amount) internal {
// @> UNSAFE: direct overwrite
allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}

Risk

Likelihood:

  • Happens whenever a user changes allowance from X to Y.

MEV bots and attackers routinely scan for these transactions.

Impact:

  • Attacker drains the old allowance

  • User sets new allowance

  • Attacker drains again → double-loss

Proof of Concept

  • Total stolen: 300.

// victim approves attacker for 100
approve(attacker, 100);
// victim wants to increase to 200
// attacker frontruns:
transferFrom(victim, attacker, 100);
// victim tx executes:
approve(attacker, 200);
// attacker now steals 200 more
transferFrom(victim, attacker, 200);

Recommended Mitigation

- remove this code
+ add this code
function _approveInternal(address owner, address spender, uint256 amount) internal {
- allowances[owner][spender] = amount;
+ uint256 current = allowances[owner][spender];
+ require(
+ current == 0 || amount == 0,
+ "UNSAFE_ALLOWANCE_CHANGE"
+ );
+ allowances[owner][spender] = amount;
}

Support

FAQs

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

Give us feedback!