Description:Title
Withdraw/Redeem functions can fail due to blocked USDT/USDC accounts
Description
Withdraw and redeem functions in smart contracts can fail if they involve transferring USDT, USDC, or other centralized stablecoins from blocked or blacklisted accounts. Both Tether (USDT) and USD Coin (USDC) are issued by centralized entities with the authority to freeze or blacklist addresses. When an account is blacklisted, any attempts to transfer these tokens from the blacklisted address will be blocked, causing the transaction to fail.
This issue can significantly impact decentralized finance (DeFi) protocols, which rely on seamless token transfers for operations like withdrawals and redemptions. If a user's address or the contract itself gets blacklisted, users may be unable to withdraw their funds, leading to a loss of trust and potentially severe financial consequences.
A potential way to fix this issue is to allow users to specify an alternative address for the transfer to go to. However, the contract must still validate that the withdrawal amount is correctly debited from the msg.sender's balance to prevent any unauthorized transfers. This ensures that users cannot steal other users' assets by specifying different addresses.
Attack Scenario
The withdraw functions listed in the PoC section of this submission show that users can initiate a energency withdraw of the TOKEN state variable which is the underlying lp token of the GaugeUpgradeable contract. This state var is set during initialization and can be set to any token, including either USDC or USDT, in fact as TOKEN is a lp token, it is exceptionally likely that it will be USDC/USDT.
Both USDC and USDT have a blacklist functionality, thus when transfer() is called in either of these token contracts, the 'from' and 'to' address are checked againt, below you can see the blacklist modifier of USDC
Therefor is a user interacts with Fenix Finance and deposits USDC or USDT in a GaugeUpgradeable contract instance with USDC/USDT as the 'TOKEN' state var and their USC/USDT address gets blacklisted, they will be unable to withdraw their assets.
This is because although the internal accounting checks _balances[msg.sender] which is good, the safeTransfer call has the 'to' address also as msg.sender, the user has no way to select what address to send their assets to so when the call goes to the USDC/USDT transfer call
msg.sender will be checked against the blacklist. This can thus prevent users from withdrawing their funds in such instances.
Github username: -- Twitter username: -- Submission hash (on-chain): 0x883a93c8b124c4fa01686ea659bb38a27ca16f395d82c2ee6e5053341ddd624b Severity: medium
Description: Title Withdraw/Redeem functions can fail due to blocked USDT/USDC accounts
Description Withdraw and redeem functions in smart contracts can fail if they involve transferring USDT, USDC, or other centralized stablecoins from blocked or blacklisted accounts. Both Tether (USDT) and USD Coin (USDC) are issued by centralized entities with the authority to freeze or blacklist addresses. When an account is blacklisted, any attempts to transfer these tokens from the blacklisted address will be blocked, causing the transaction to fail.
This issue can significantly impact decentralized finance (DeFi) protocols, which rely on seamless token transfers for operations like withdrawals and redemptions. If a user's address or the contract itself gets blacklisted, users may be unable to withdraw their funds, leading to a loss of trust and potentially severe financial consequences.
A potential way to fix this issue is to allow users to specify an alternative address for the transfer to go to. However, the contract must still validate that the withdrawal amount is correctly debited from the msg.sender's balance to prevent any unauthorized transfers. This ensures that users cannot steal other users' assets by specifying different addresses.
Attack Scenario
The withdraw functions listed in the PoC section of this submission show that users can initiate a energency withdraw of the TOKEN state variable which is the underlying lp token of the GaugeUpgradeable contract. This state var is set during initialization and can be set to any token, including either USDC or USDT, in fact as TOKEN is a lp token, it is exceptionally likely that it will be USDC/USDT.
Both USDC and USDT have a blacklist functionality, thus when transfer() is called in either of these token contracts, the 'from' and 'to' address are checked againt, below you can see the blacklist modifier of USDC
Therefor is a user interacts with Fenix Finance and deposits USDC or USDT in a GaugeUpgradeable contract instance with USDC/USDT as the 'TOKEN' state var and their USC/USDT address gets blacklisted, they will be unable to withdraw their assets.
This is because although the internal accounting checks _balances[msg.sender] which is good, the safeTransfer call has the 'to' address also as msg.sender, the user has no way to select what address to send their assets to so when the call goes to the USDC/USDT transfer call msg.sender will be checked against the blacklist. This can thus prevent users from withdrawing their funds in such instances.
Attachments
['289']
['301']
Function Block 1
Function Block 2
The solutions above allow the user to specify what address to withdraw to without needing to modify any internal accounting operations.