Core Contracts

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

Decimal Mismatch in Token Redemption

Summary

USDC has 6 decimals and ZENO was implemented with 18 decimals by default since it's using Openzeppelin.

Vulnerability Details

We have a serious problem here, the ZENO token is a 18 decimal one implemented by default but USDC has 6 decimals, so when using these two functions to transfer the same amount of USDC to the user they will actually be getting way more USDC then they should, regardless of the idea of the dev here, if is 1 to 1 or any other type really this seems to easy to play the system since 1 ZENO (1e18) and 1 USDC (1e6), the user can get much more USDCs then he should.

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/zeno/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);
}
function redeemAll() external nonReentrant {
if (!isRedeemable()) {
revert BondNotRedeemable();
}
uint256 amount = balanceOf(msg.sender);
totalZENORedeemed += amount;
_burn(msg.sender, amount);
USDC.safeTransfer(msg.sender, amount);
}

Impact

lets say the user has 1 Zeno (1e18) and the code above sends that same amount in USDCs because there is no convertion, so instead of 1 USDC equivalent he would be sending much more than that and gaming the system. but regardless of the logic the dev thought, not converting these two assets seems really strange and gameable.

At least I see the system breaking by trying to send too much USDC which the contract wont have that much because 1e18 usdc is a lot. (1e18 USDC is 1 quintillion dollars, or $1,000,000,000,000,000,000.)

Tools Used

manual

Recommendations

convert the two assets with different decimals to behave exactly as expected.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 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.

Give us feedback!