USDT approvals work differently than the other ERC20 contracts. For USDT, .approve() function cannot be called for updating allowances from a non-zero value to a non-zero value.
Proof of Concept
This instance in the code is trying to change the allowance to a non-zero value but in case of multiple deposits for USDT token, the approval will fail and will cause the following operations to break.
Instead of calling the .approve() function directly, a second line of code can be added which sets the approval to zero first and then sets it back to the desired amount. For eg:
Lines of code
https://github.com/code-423n4/2022-03-volt/blob/main/contracts/pcv/compound/ERC20CompoundPCVDeposit.sol#L31
Vulnerability details
Impact
USDT approvals work differently than the other ERC20 contracts. For USDT,
.approve()
function cannot be called for updating allowances from a non-zero value to a non-zero value.Proof of Concept
This instance in the code is trying to change the allowance to a non-zero value but in case of multiple deposits for USDT token, the approval will fail and will cause the following operations to break.
https://github.com/code-423n4/2022-03-volt/blob/main/contracts/pcv/compound/ERC20CompoundPCVDeposit.sol#L31
Tools Used
Manual checks
Recommended Mitigation Steps
Instead of calling the
.approve()
function directly, a second line of code can be added which sets the approval to zero first and then sets it back to the desired amount. For eg:Another alternative would be to use 'increaseAllowance
and
decreaseAllowance` from the ERC20 contracts.