Core Contracts

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

Unhandled Unsold ZENO Tokens in Auction Contract

Summary

The Auction.sol contract does not provide a mechanism to handle unsold ZENO tokens after the auction ends (block.timestamp >= state.endTime) when totalRemaining > 0. The zeno.mint function is only called during the buying process, and there is no withdrawal function for the owner or businessAddress to retrieve the remaining ZENO. This results in unsold tokens being permanently locked in the contract, reducing the expected circulating supply and potentially disrupting the token economy without any recovery option.

Vulnerability Details

The contract initializes an auction with a fixed totalAllocated amount of ZENO tokens available for sale, tracked via state.totalRemaining. During the auction (startTime to endTime), the buy function mints ZENO to buyers and reduces totalRemaining.

  • If the auction concludes (block.timestamp >= state.endTime) and totalRemaining > 0 (i.e., not all ZENO tokens are sold), there is no function to withdraw or reallocate the unsold tokens. The zeno.mint function is only invoked within buy, and no administrative function exists to access totalRemaining post-auction.

  • This design oversight leaves unsold ZENO tokens effectively locked in the contract, as the contract does not own ZENO tokens directly but relies on the ZENO contract to mint them, and no further minting is triggered after endTime.

Impact

  • Loss of control over unsold assets,

  • Reduced trust in the auction mechanism

  • Potential economic misalignment in the RAAC ecosystem.

Tools Used

Manual Review

Recommendations

Add a Finalization Function:

bool public isFinalized;
function finalizeAuction() external onlyOwner {
require(block.timestamp >= state.endTime, "Auction not ended");
require(!isFinalized, "Auction already finalized");
if (state.totalRemaining > 0) {
zeno.mint(businessAddress, state.totalRemaining);
state.totalRemaining = 0;
isFinalized = true;
emit AuctionFinalized(state.totalRemaining);
}
}

with isFinalized variable to track whether the auction has been finalized to prevent double finalization with a new event AuctionFinalized.

event AuctionFinalized(uint256 remainingAmount);
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!