Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: medium
Invalid

Only users who buy deToken are able to redeem it

Summary

Vulnerability Details

DEToken is a normal token which is minted by the stability pool and is tradable 1:1 for rToken

This can be seen in the comments

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/tokens/DEToken.sol#L15

* DEToken is redeemable 1:1 with RToken.

And it's implementation of transfer and transferFrom

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/tokens/DEToken.sol#L109

function transfer(address recipient, uint256 amount) public override(ERC20,IERC20) onlyStabilityPool returns (bool) {
return super.transfer(recipient, amount);
}
function transferFrom(address sender, address recipient, uint256 amount) public override(ERC20,IERC20) onlyStabilityPool returns (bool) {
return super.transferFrom(sender, recipient, amount);
}

However even though it's tradable it's not redeemable as withdraw does this crucial check before burning your tokens.

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/pools/StabilityPool/StabilityPool.sol#L224

function withdraw(uint256 deCRVUSDAmount) external nonReentrant whenNotPaused validAmount(deCRVUSDAmount) {
// ...
if (userDeposits[msg.sender] < rcrvUSDAmount) revert InsufficientBalance();
userDeposits[msg.sender] -= rcrvUSDAmount;

In short this means that if you weren't the one that bought them, then you are not able to redeem them. This is not wanted and it break the whole concept of freely transferable tokens as even if someone buys those tokens and hold them they won't be able to redeem them.

Impact

Some tokens will end up stuck as the original redeemer won't want the anymore
Users who bought this freely traded token won't be able to redeem it
The token then won't be useful for anyone else but the ones that bought it.

Tools Used

Manual review

Recommendations

Remove this check and only burn the token.

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/pools/StabilityPool/StabilityPool.sol#L224

function withdraw(uint256 deCRVUSDAmount) external nonReentrant whenNotPaused validAmount(deCRVUSDAmount) {
_update();
if (deToken.balanceOf(msg.sender) < deCRVUSDAmount) revert InsufficientBalance();
uint256 rcrvUSDAmount = calculateRcrvUSDAmount(deCRVUSDAmount);
uint256 raacRewards = calculateRaacRewards(msg.sender);
- if (userDeposits[msg.sender] < rcrvUSDAmount) revert InsufficientBalance();
- userDeposits[msg.sender] -= rcrvUSDAmount;
deToken.burn(msg.sender, deCRVUSDAmount);
rToken.safeTransfer(msg.sender, rcrvUSDAmount);
Updates

Lead Judging Commences

inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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