Some tokens (like USDT) do not work when changing the allowance from an
existing non-zero allowance value. They must first be approved by zero and then the actual allowance must be approved.
Also approve() will fail for certain token implementations that do not return a boolean value. Hence it is recommend to use safeIncreaseAllowance() and safeDecreaseAllowance
Lines of code
https://github.com/code-423n4/2022-12-tigris/blob/0cb05a462e78c4470662e9d9a4f9ab587f266bb5/contracts/Trading.sol#L652 https://github.com/code-423n4/2022-12-tigris/blob/0cb05a462e78c4470662e9d9a4f9ab587f266bb5/contracts/Lock.sol#L117
Vulnerability details
ERC20
approve
can fail for some tokensImpact
Some tokens (like
USDT
) do not work when changing the allowance from an existing non-zero allowance value. They must first be approved by zero and then the actual allowance must be approved.Also
approve()
will fail for certain token implementations that do not return a boolean value. Hence it is recommend to usesafeIncreaseAllowance()
andsafeDecreaseAllowance
Proof of Concept
USDT
approve()
return value ignoredhttps://github.com/code-423n4/2022-12-tigris/blob/0cb05a462e78c4470662e9d9a4f9ab587f266bb5/contracts/Trading.sol#L652 IERC20(_marginAsset).approve(_stableVault, type(uint).max);
https://github.com/code-423n4/2022-12-tigris/blob/0cb05a462e78c4470662e9d9a4f9ab587f266bb5/contracts/Lock.sol#L117 IERC20(assets[i]).approve(address(bondNFT), type(uint256).max);
Mitigation
approve
beforeapprove
safeIncreaseAllowance
andsafeDecreaseAllowance
instead ofapprove
revert
/emit
events if needed