Closed code423n4 closed 2 years ago
Personally I remember encountering this report in other contests and Med Severity doesn't sit well with me.
Checking the standard:
The attack is clearly mentioned and it's up to the F-E / Injected Wallet to approve 0, not up to the contract as to maintain backwards compatibility.
Additionally I've written about my thoughts in the Yield Contest: https://github.com/code-423n4/2022-01-yield-findings/issues/6
For the reasons mentioned above, I respect the warden's submission but will downgrade to QA as I believe the report is useful but ultimately non-critical
Lines of code
https://github.com/code-423n4/2022-05-backd/blob/2a5664d35cde5b036074edef3c1369b984d10010/protocol/contracts/StakerVault.sol#L185-L189
Vulnerability details
Impact
The
StakerVault
contract doesn't protect against the "Multiple Withdrawal Attack" where:approve()
s amount X for Bobapprove()
s X+N for Bob instead, intending for X+N to replace Xapprove()
call is still in the mempool, Bob front-runs the approval with atransferFrom()
for the original X amount by providing a high gas feeapprove()
call is added to a block, Bob transfers the new X+N amountBob was able to get 2X+N rather than X+N
This was found to be of Medium risk in a prior contest
Proof of Concept
https://github.com/code-423n4/2022-05-backd/blob/2a5664d35cde5b036074edef3c1369b984d10010/protocol/contracts/StakerVault.sol#L185-L189
There are no checks that the existing value is zero
Tools Used
Code inspection
Recommended Mitigation Steps
One way to handle the issue is to add
require(0 == allowance[msg.sender][spender] || 0 == amount)
, which will prevent EOA accounts from hitting the problem. For contract accounts, OpenZeppelin'sERC20
has functionsincreaseAllowance()
anddecreaseAllowance()
which useallowance()
calls in order to atomically change balances