This issue is similar to the well-known double-spend problem in the ERC20 approve function. A user may transfer out more tokens than the owner approved by front-running the transactions, which set the user's allowance to a different value.
Proof of Concept
The owner calls approveTransferERC20(DAI, Alice, 10) to approve Alice to transfer 10 DAI from the vault.
After some time, the owner decides to change the allowance to 5, so he calls approveTransferERC20(DAI, Alice, 5).
Alice, who keeps monitoring the transactions in the mempool, notices the transaction sent in Step 2. She then front-runs that transaction (by either a higher gas price or using flashbot bundles) and calls delegatedTransferERC20(DAI, Alice, 10) to transfer 10 DAI out of the vault.
The transaction sent in Step 2 successfully executes and sets the allowance of Alice to 5.
Alice then transfers out 5 more DAI by calling delegatedTransferERC20 again. As a result, she could transfer more tokens from the vault than the owner intended.
sponsor acknowledged
disagree with severity 1
This issue with ERC20 approve pattern is noted. We will switch to an increase,decrease approval in next vault update.
(experimental feature)
Handle
shw
Vulnerability details
Impact
This issue is similar to the well-known double-spend problem in the ERC20
approve
function. A user may transfer out more tokens than the owner approved by front-running the transactions, which set the user's allowance to a different value.Proof of Concept
approveTransferERC20(DAI, Alice, 10)
to approve Alice to transfer 10 DAI from the vault.approveTransferERC20(DAI, Alice, 5)
.delegatedTransferERC20(DAI, Alice, 10)
to transfer 10 DAI out of the vault.delegatedTransferERC20
again. As a result, she could transfer more tokens from the vault than the owner intended.Referenced code:
Visor.sol#L430-L463
Tools Used
None
Recommended Mitigation Steps
Implement the
increaseAllowance
anddecreaseAllowance
functions instead, as suggested by OpenZeppelin's ERC20 implementation.