Core Contracts

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

Users will not receive the correct amount when they exchange the bought ZENO tokens for USDC

Summary

After the timelimit users can exchange their ZENO(tokens that they previously bought) for their USDC, but they will not receive the correct amount, because of the Redeem or RedeemAll function.

Vulnerability Details

In the Auction contract you can buy Zeno tokens in exchange for USDC, which they will be returned to you after the time(MATURITY_DATE), by the function redeem.

First lets look at the Buy function in the Auction contract

function buy(uint256 amount) external whenActive {
require(amount <= state.totalRemaining, "Not enough ZENO remaining");
uint256 price = getPrice();
uint256 cost = price * amount;
require(usdc.transferFrom(msg.sender, businessAddress, cost), "Transfer failed");
bidAmounts[msg.sender] += amount;
state.totalRemaining -= amount;
state.lastBidTime = block.timestamp;
state.lastBidder = msg.sender;
zeno.mint(msg.sender, amount);
emit ZENOPurchased(msg.sender, amount, price);
}
function getPrice() public view returns (uint256) {
//code
return state.startingPrice
- (
(state.startingPrice - state.reservePrice) * (block.timestamp - state.startTime)
/ (state.endTime - state.startTime)
);
}

As we can see the user has to set an amount that will be multiplied by the price of the Auction and then only the amount is going to be minted to the user.

Now lets see the Redeem function ->

function redeemAll() external nonReentrant {
if (!isRedeemable()) {
revert BondNotRedeemable();
}
uint256 amount = balanceOf(msg.sender);
totalZENORedeemed += amount;
_burn(msg.sender, amount);
USDC.safeTransfer(msg.sender, amount);// <= it should be amount * getPrice()
}

When the user tries to exchange their ZENO tokens for their USDC, they will only receive the amount they bought, but not multiplied by the Price.

Here is an example ->
In the docs it is stated that the zeno tokens are fully backed by USDC, which means 1:1

the price of the Auction right now is = 100 $

  1. Alice wants to buy 10 tokens of zeno from this auction, she will use buy(10) and transfer 1000 $ of USDC and will receive only 10 zeno tokens

  2. The block.timestamp is bigger than the maturity date and Alice now can exchange her ZENO tokens for USDC

  3. She uses redeemAll or redeem, but only receive 10 USDC

Impact

lost of funds for the users

Tools Used

Recommendations

In redeemAll and redeem multiply the amount by the price of the auction

Updates

Lead Judging Commences

inallhonesty Lead Judge 5 months ago
Submission Judgement Published
Validated
Assigned finding tags:

ZENO.sol implements fixed 1:1 redemption with USDC regardless of auction purchase price, breaking zero-coupon bond economics and causing user funds to be permanently lost

Support

FAQs

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