Alice calls the approve function and approves Bob to spend 1000 tokens. But then alice changes the approve amount from 1000 to 500 tokens. Bob notices this and tries to exploit this. He front-runs the 2nd approve() call , by providing more gas, and withdraws 1000 tokens (as the 2nd approve call has not yet been mined). The 2nd approve call is now mined, and the approve amount is changed to 500 tokens. He then again withdraws the 500 tokens . Thus using front-running, Bob was able to spend 1500 tokens, but he was approved to spend 500 tokens only.
Lines of code
https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Velo.sol#L36
Vulnerability details
Impact
Alice calls the approve function and approves Bob to spend 1000 tokens. But then alice changes the approve amount from 1000 to 500 tokens. Bob notices this and tries to exploit this. He front-runs the 2nd approve() call , by providing more gas, and withdraws 1000 tokens (as the 2nd approve call has not yet been mined). The 2nd approve call is now mined, and the approve amount is changed to 500 tokens. He then again withdraws the 500 tokens . Thus using front-running, Bob was able to spend 1500 tokens, but he was approved to spend 500 tokens only.
Proof of Concept
https://github.com/code-423n4/2022-05-velodrome/blob/main/contracts/contracts/Velo.sol#L36
Tools Used
Manual review
Recommended Mitigation Steps
Use increaseAllowance or decreaseAllowance instead of approve