The redeem and redeemAll functions in the ZENO.sol contract fail to account for the difference in decimal places between ZENO (18 decimals) and USDC (6 decimals). As a result, users may receive an incorrect amount of USDC when redeeming ZENO tokens. This can lead to a severe financial imbalance where users may either receive excess or insufficient USDC, making the contract vulnerable to exploitation.
In Solidity, ERC-20 tokens typically have a decimals function that returns the number of decimal places the token uses. Since your ZENO.sol contract inherits from ERC20, the decimals() function is already defined in OpenZeppelin's ERC20 contract.
This is the link to the OpenZeppelin documentation for ERC20:
By default, ERC20 uses a value of 18 for decimals.
To use a different value, you will need to override thedecimals()function in your contract.
So, the default decimals in OpenZeppelin’s ERC20 contract is 18 unless overridden.
Since, the ZENO.sol contract does not override the decimals() function, ZENO has 18 decimals by default.
This is the ZENO.sol smart contract:
ZENO tokens have 18 decimals (1 ZENO = 10¹⁸ smallest units).
USDC tokens have 6 decimals (1 USDC = 10⁶ smallest units).
The redeem and redeemAll function directly transfers amount of USDC without adjusting for decimal difference.
This causes a 1e12 (10¹²) scaling error, leading to significant financial discrepancies.
User holds 1 ZENO (which is 1 * 10¹⁸ in its smallest unit).
Expected USDC equivalent should be 1 USDC (which is 1 * 10⁶ in its smallest unit).
However, due to the lack of decimal conversion, the contract transfers 1 * 10¹⁸ USDC, which is 1 trillion times the expected amount!
A user calls redeem(1 * 10¹⁸).
The contract burns 1 ZENO.
The contract transfers 1 * 10¹⁸ USDC instead of 1 * 10⁶ USDC.
The user receives excess USDC, leading to a financial imbalance.
High: Users can receive a significantly larger amount of USDC than expected, causing loss of funds for the protocol.
High: Alternatively, if the contract were modified for a different conversion rate, users might receive significantly less USDC than they should.
Critical Financial Risk: If exploited, users can drain the USDC reserves by repeatedly redeeming ZENO tokens.
Manual Review
To fix this issue, ensure proper decimal conversion before transferring USDC
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.