Core Contracts

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

Incorrect handling of USDC and Zeno token due to difference in decimals

Summary

There's an issue in the Zeno and USDC parity due to lack of accounting regarding difference of decimals.

Vulnerability Details

Zero is an ERC20 inherited from openzeppelin which doesn't modify the existing decimals, therefore it will have 18 decimals. USDC, on the ethereum mainnet, has 6 decimals.

Not taking the difference in decimals will lead to incorrect accounting in Zeno.sol and Auction.sol.

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/zeno/Auction.sol#L84-L97

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/zeno/ZENO.sol#L34-L40

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/zeno/ZENO.sol#L46-L63

For example, if the input is in 18 decimals.

Auction.buy() gets called with 100e18, user would transfer 100000000000000e6 usdc and mint 1e18 zeno. It would just revert since it's too much usdc.

And for example, if the input is in 6 decimals.

Auction.buy() gets called with 100e6, user would transfer 100e6 usdc and mint 0.0000000001e18 zeno.

Impact

Incorrect accounting due to usdc having 6 decimals and zeno having 18 decimals. The flow of Auction.buy() -> Zeno.mint() -> Zeno.redeem() will not work. In the input is in 18 decimals the TX it will revert. If it's in 18 decimals, a very small amount of Zeno tokens will be minted.

Tools Used

Manual Review.

Recommendations

Need to account for the difference in decimals. One solution can be to assume function inputs are done with 18 decimals (since zero was 18 decimals), and when transferring usdc take into account the usdc.decimals().

In Zeno.redeem()

USDC.safeTransfer(msg.sender, (amount * USDC.decimals()) / 1e18);

In Auction.buy()

usdc.transferFrom(msg.sender, businessAddress, (cost * usdc.decimals()) / 1e18);
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

Auction.sol's buy() function multiplies ZENO amount (18 decimals) by price (6 decimals) without normalization, causing users to pay 1 trillion times the intended USDC amount

Support

FAQs

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

Give us feedback!