The _spendAllowance() function always decrements the allowance, even when set to type(uint256).max (the standard "infinite approval" pattern).
Standard implementations skip the decrement for max approval to save gas and provide expected UX.
Likelihood:
Affects every user who sets infinite approval (common DEX pattern)
Standard practice for Uniswap, 1inch, and most DeFi protocols
Impact:
Unexpected allowance changes when users expect "unlimited"
Extra ~5000 gas per transferFrom due to unnecessary SSTORE
Breaks user expectations from standard ERC20 behavior
This test demonstrates that setting type(uint256).max as an allowance (the standard "infinite approval" pattern used by DEXes) does not behave as expected. After a single transfer, the allowance is decremented rather than remaining at max. This wastes gas and confuses users who expect infinite to mean infinite.
Place this test in test/InfiniteApprovalPOC.t.sol and run with forge test --match-test test_MaxApprovalIsDecremented -vv:
Check if the current allowance equals type(uint256).max before performing the decrement. In Yul, not(0) equals type(uint256).max. If infinite approval is detected, skip both the sufficiency check (it will always pass) and the storage write (unnecessary gas cost).
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.