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.
Proof of Concept
The following function use an unsafe approvement which can fail and cause the functions to revert:
AxelarDepositService.sendNative - if the wrapped token is a token like that, it will simply DoS the sendNative after the first user uses it.
ReceiverImplementation.receiveAndSendNative - the same as before, but the risk here is worst because it can cause users' funds to be lost - if they manage to send Native tokens on one chain but not manage to get them on the other one.
ReceiverImplementation.receiveAndSendToken - here a token like USDT can cause the function to revert and it means that users won't be able to transfer USDT after the first time (first approval), if the token transfer hasn't happened yet (which means the approval is not zero).
Tools Used
Manual audit
Recommended Mitigation Steps
Approve to zero first or use increase and decrease allowance functions instead.
Lines of code
https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/deposit-service/AxelarDepositService.sol#L30 https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/deposit-service/ReceiverImplementation.sol#L38 https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/deposit-service/ReceiverImplementation.sol#L64
Vulnerability details
Impact
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.
Proof of Concept
The following function use an unsafe approvement which can fail and cause the functions to revert:
AxelarDepositService.sendNative
- if the wrapped token is a token like that, it will simply DoS thesendNative
after the first user uses it.ReceiverImplementation.receiveAndSendNative
- the same as before, but the risk here is worst because it can cause users' funds to be lost - if they manage to send Native tokens on one chain but not manage to get them on the other one.ReceiverImplementation.receiveAndSendToken
- here a token like USDT can cause the function to revert and it means that users won't be able to transfer USDT after the first time (first approval), if the token transfer hasn't happened yet (which means the approval is not zero).Tools Used
Manual audit
Recommended Mitigation Steps
Approve to zero first or use increase and decrease allowance functions instead.