Beginner FriendlyFoundryDeFiOracle
100 EXP
View results
Submission Details
Severity: medium
Valid

Users Funds Can Get Permanently Stuck in `AssetToken`

Summary

Implementation of setAllowedToken results in the liquidity provider by users getting stuck in the AssetToken contract because there is no mechanism to withdraw assets after disabling a token.

Vulnerability Details

Let's assume the owner enables a token to be accepted in the protocol, then users will deposit that token as liquidity. Later the owner calls setAllowedToken to disable the token.

At this point the users cannot withdraw their assets from the protocol; enabling the token again will only result in a brand new AssetToken being created that will point to a different address that doesn't have the balance of the users.

AssetToken mainly provides basic ERC-20 logic and all deposit and redemption logics are in ThunderLoan/ThunderLoanUpgraded. This mean the users cannot use AssetToken directly to get their assets back.

Proof Of Concept

The following code snippet shows an example of the vulnerability.

POC
function testAudit__UserFundsLockedAfterTokenDisabled() public {
// owner enable token
vm.startPrank(owner, owner);
AssetToken assetToken1 = thunderLoan.setAllowedToken(IERC20(address(tokenA)), true);
// user provide liquidity
vm.startPrank(liquidityProvider, liquidityProvider);
thunderLoan.deposit(IERC20(address(tokenA)), DEPOSIT_AMOUNT);
// owner disables the token
vm.startPrank(owner, owner);
thunderLoan.setAllowedToken(IERC20(address(tokenA)), false);
// owner enables the token again
vm.startPrank(owner, owner);
AssetToken assetToken2 = thunderLoan.setAllowedToken(IERC20(address(tokenA)), true);
// after enabling the token again, a new `AssetToken` contract is deployed
assertNotEq(address(assetToken1), address(assetToken2));
// user cannot withdraw their assets
vm.expectRevert("ERC20: burn amount exceeds balance");
vm.startPrank(liquidityProvider, liquidityProvider);
thunderLoan.redeem(IERC20(address(tokenA)), DEPOSIT_AMOUNT / 2);
}

Impact

Lost of users funds.

Tools Used

VS Code and Foundry.

Recommendations

Disallow disabling a token if the contract holds underlying balance or provide a channel for users to withdraw their assets if the token is disabled.

Updates

Lead Judging Commences

0xnevi Lead Judge
almost 2 years ago
0xnevi Lead Judge almost 2 years ago
Submission Judgement Published
Invalidated
Reason: Admin Input/call validation
0xnevi Lead Judge almost 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

centralized owners can brick redemptions by unallowing a token

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.