During auction the price to determine the cost of usdc to zeno Token we have;
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);
}
A user attempts to purchase 10 ZENO tokens (10e18).
Assuming price = 1e6 (1 USDC)
cost = price * amount
= 1e6 * 10e18
= 10e24
= 10,000,000,000,000,000,000 USDC
The user would need to pay 10 quintillion USDC to purchase 10 ZENO tokens, which is infeasible.
Impact
users cannot purchase zeno tokens due to missing normalization of token decimals
Recommendation
consider the following changes
https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/zeno/Auction.sol#L87
function buy(uint256 amount) external whenActive {
require(amount <= state.totalRemaining, "Not enough ZENO remaining");
uint256 price = getPrice();
- uint256 cost = price * amount;
+ uint256 cost = price * amount / 1e18;
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);
}
https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/zeno/ZENO.sol#L73
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);
+ uint256 amountUsdc = amount / 1e12;//@audit possibly include an exchangeRate to give a fairer conversion
+ USDC.safeTransfer(msg.sender, amountUsdc);
}