Core Contracts

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

Blacklisted Users Unable to Redeem ZENO Tokens in ``ZENO.sol::redeem``

Summary

A user who participates in the ZENO token auction by purchasing ZENO with USDC may lose their funds permanently if their wallet address gets blacklisted by the USDC contract before the maturity period. This prevents them from redeeming their ZENO tokens for USDC, effectively locking their assets with no way to recover them.

Vulnerability Details

Issue Description

  1. User purchases ZENO tokens

    • The user buys ZENO tokens by calling the buy() function in Auction.sol, which transfers USDC from the user’s wallet to the business address and mints ZENO tokens to the user.

    • The function implementation:

      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);
      }
    • At this point, the user has successfully exchanged their USDC for ZENO.

  2. Maturity Period

    • ZENO tokens can only be redeemed for USDC after the maturity date.

    • The maturity check:

      function isRedeemable() public view returns (bool _redeemable) {
      _redeemable = (block.timestamp >= MATURITY_DATE);
      }
  3. User Attempts to Redeem ZENO for USDC

    • After the maturity date, users call the redeem() function to exchange their ZENO tokens for USDC.

    • The implementation of redeem() in ZENO.sol:

      function redeem(uint amount) external nonReentrant {
      if (!isRedeemable()) {
      revert BondNotRedeemable();
      }
      if (amount == 0) {
      revert ZeroAmount();
      }
      uint256 totalAmount = balanceOf(msg.sender);
      if (amount > totalAmount) {
      revert InsufficientBalance();
      }
      totalZENORedeemed += amount;
      _burn(msg.sender, amount);
      USDC.safeTransfer(msg.sender, amount);
      }
    • The contract calls USDC.safeTransfer(msg.sender, amount), attempting to send the USDC back to the user.

  4. User Gets Blacklisted Before Redemption

    • If the USDC contract blacklists the user's address, they cannot receive USDC transfers.

    • The safeTransfer() function will fail, and the user will never receive their redeemed USDC, even though their ZENO tokens are burned.

    • Key problem: There is no error handling for blacklisted addresses, meaning the redemption process silently fails without providing an alternative way to recover funds.

Impact

  • User Funds Are Lost:

    • A blacklisted user can never redeem their ZENO tokens for USDC.

    • Their ZENO tokens are burned, but the corresponding USDC is not received, leading to a one-sided loss.

  • Funds Get Locked in the Contract:

    • The USDC meant for blacklisted users remains stuck in the contract, leading to fund mismanagement.

Tools Used

  • Manual Code Review

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!