The ThunderLoan protocol allows liquidity providers to deposit ERC20 tokens via deposit() in exchange for AssetTokens (LP tokens). The mintAmount is calculated as (amount * EXCHANGE_RATE_PRECISION) / exchangeRate, which at a 1:1 rate simply equals the raw amount passed in. The AssetToken is a standard ERC20 with 18 decimals.
The deposit() function does not normalize the deposited amount to account for the difference in decimals between the underlying token and the AssetToken (always 18 decimals). When a token with fewer decimals (e.g. USDC/USDT with 6 decimals) is deposited, the user receives a drastically incorrect amount of AssetTokens. For example, depositing 1000 USDC (1e9 raw) mints only 1e9 raw AssetTokens, which equals 0.000000001 AssetTokens in human-readable terms instead of the expected 1000. This is an error factor of 10121012.
Likelihood:
When USDT,USDC or ZIL are allowed, they have not 18 decimals
Every single deposit of a non-18-decimal token triggers this bug — there is no edge case or special condition required, it happens on the standard execution path.
Impact:
Liquidity providers depositing tokens with fewer than 18 decimals receive a negligible amount of AssetTokens (off by a factor of 10(18−tokenDecimals)10(18−tokenDecimals)), resulting in a near-total loss of their deposited funds upon redeem().
the fee (calculated on the raw amount) is added to a tiny totalSupply, causing the exchange rate to spike to absurd values, corrupting the accounting for all subsequent depositors, redeemers, and flash loan borrowers of that token.
The test deploys ThunderLoan with a 6-decimal ERC20 token (simulating USDC/USDT) and has a user deposit 1000 tokens. It then verifies three things:
The protocol mints only 1e9 raw AssetTokens (equal to the raw deposit amount) instead of the correct 1000e18.
The actual minted amount does not match the expected normalized value of 1000e18.
The error factor between expected and actual is exactly 1e12 (1018−61018−6), proving the protocol fails to normalize for the decimal difference.
This demonstrates that a liquidity provider depositing 1000 USDC effectively receives 0.000000001 AssetTokens instead of 1000, a near-total loss of value representation.
1- Remove USDC,USDT and ZIL from possible allowed tokens
2- Implement a function that normalize decimals before any accounting
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.