Core Contracts

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

Wrong calculation in ZENO::redeem function leads to incorrect redemption amounts

Summary

The ZENO contract contains a critical vulnerability in its redeem and redeemAll functions where token redemption calculations fail to account for decimal scaling between ZENO (18 decimals) and USDC (6 decimals). This mismatch leads to the contract attempting to transfer 1e12 times more USDC than intended, causing all redemptions to fail due to insufficient USDC balance.

Vulnerability Details

In both redeem and redeemAll functions, ZENO tokens are burned and USDC is transferred without accounting for decimal differences:

function redeem(uint amount) external nonReentrant {
// ... input validation ...
totalZENORedeemed += amount;
_burn(msg.sender, amount);
USDC.safeTransfer(msg.sender, amount); // @audit - amount not scaled
}
function redeemAll() external nonReentrant {
// ... input validation ...
totalZENORedeemed += amount;
_burn(msg.sender, amount);
USDC.safeTransfer(msg.sender, amount); // @audit - amount not scaled
}

When a user attempts to redeem 1 ZENO token:

  1. Input amount = 1e18 (1 ZENO in base units)

  2. Contract burns 1e18 ZENO (correct)

  3. Contract attempts to transfer 1e18 USDC (should be 1e6)

  4. Transfer fails as contract has insufficient USDC

Impact

  1. Complete denial of service for token redemptions as the USDC transfer will always fail

  2. All redemption functionality is blocked, preventing users from claiming their USDC

Tools Used

Manual Review

Recommendations

Fix the decimal scaling in both functions:

function redeem(uint256 amount) external nonReentrant {
...
totalZENORedeemed += amount;
_burn(msg.sender, amount);
- USDC.safeTransfer(msg.sender, amount);
+ USDC.safeTransfer(msg.sender, amount / 1e12);
}
function redeemAll() external nonReentrant {
...
uint256 amount = balanceOf(msg.sender);
totalZENORedeemed += amount;
_burn(msg.sender, amount);
- USDC.safeTransfer(msg.sender, amount);
+ USDC.safeTransfer(msg.sender, amount / 1e12);
}
Updates

Lead Judging Commences

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

Decimal precision mismatch between ZENO token (18 decimals) and USDC (6 decimals) not accounted for in redemption, causing calculation errors and incorrect payments

Support

FAQs

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