Approval Vulnerabilities¶
Approvals are a fundamental component of tokens on Ethereum. They grant a third-party address, either an externally owned account (EOA) or another smart contract, permission to move funds on the owner's behalf. NFT marketplaces and DeFi applications rely on the mechanism to automate transfers once a trade completes or once business logic conditions are met.
Unlimited Approvals¶
A prevalent misstep is requiring unlimited approvals for certain assets, usually justified by the system's lack of knowledge of the amount needed at a given time. Once granted, an approval is invocable at any point in the future. An attacker who compromises the smart contract system exploits those approvals and drains every previously approved asset for the affected address.
Approval Frontrunning¶
The approval system is also susceptible to frontrunning. Submitting multiple approve calls opens a window of opportunity for malicious actors:
- Using the
approvefunction, a user allows a smart contract system to transferxof their ERC20 tokens. - Later, they opt to modify the allowance to
yand thus send anotherapproverequest. - In the meantime, before the user-given transaction gets included, an attacker initiates the
transferFromfunction to removextokens from the user's wallet. - If the attacker's transaction is processed first, followed by the user's new
approvetransaction, the malicious actor can move an additionalytokens. - The aggregate unauthorized transfer amounts to
x+ytokens.
The vulnerability arises because the ERC20 _approve function sets the spender's allowance directly:
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
The _spendAllowance function verifies only the current allowance against the amount specified in the transferFrom call. It tracks no funds transferred before the latest approve request:
1 2 3 4 5 6 7 8 9 10 11 | |
Mitigations¶
The straightforward countermeasure against the frontrunning race is to change how the allowance is managed. Instead of setting new values through direct approve calls, the safeIncreaseAllowance and safeDecreaseAllowance functions from OpenZeppelin's SafeERC20 implementation take a value difference rather than an absolute amount, and internally call the target's approve function.
A second threat, though not a smart contract vulnerability in the strict sense, is approval phishing. Where a frontend is exposed to content injection or other manipulation, attackers modify the underlying code to divert approvals to an address of their own rather than to the intended smart contract.
An allowance system that caps an approval at the immediately necessary amount limits the blast radius of both. Two-step transfers and locking periods reduce the impact of malicious actions further, at the cost of user-friendliness. On the user side, periodic review of granted approvals and revocation of outdated ones closes the exposure, and platforms such as revoke.cash exist for that purpose.