The invariant is that The ZENO contract's USDC balance must always be ≥ totalZENORedeemed. However this is broken.
The Auction contract sends USDC to businessAddress during purchases, not to the ZENO contract.
The ZENO contract’s redeem function attempts to transfer USDC from its own balance to users, but it never receives USDC.
totalZENORedeemed will always exceed the ZENO contract’s USDC balance (which is permanently zero).
All redemption attempts will fail due to USDC.safeTransfer reverting.
Auction mints 100 ZENO to Alice via mint() → totalZENOMinted = 100.
Auction sends 100 USDC to businessAddress (not ZENO contract).
After maturity, Alice calls redeem(100).
Contract checks balanceOf(Alice) = 100 → proceeds.
USDC.safeTransfer tries to send 100 USDC from ZENO’s balance (which is 0) → reverts.
All redemption attempts will fail due to USDC.safeTransfer reverting.
Manual Review
Deposit USDC into ZENO Contract: Modify the Auction’s buy function to send USDC to the ZENO contract (not businessAddress). This ensures the ZENO contract holds sufficient USDC for redemptions.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.