getCalculatedFee divides the borrowed value by the precision before multiplying by the fee rate. Integer truncation in the intermediate result discards value that could contribute to the final fee, so loans are systematically undercharged even when token and oracle decimals are otherwise correctly aligned.
At ThunderLoan.sol:248-250:
valueOfBorrowedToken = (amount * price) / precision;
fee = (valueOfBorrowedToken * flashLoanFee) / precision;
The first division rounds down. Multiplying after that division cannot recover the discarded remainder. This is distinct from the token-decimal mismatch: it occurs within a valid common scale due solely to operation ordering.
LPs lose a small portion of fees on many loans, and boundary amounts can be charged less than the configured percentage.
Use full-precision multiplication/division (for example OpenZeppelin Math.mulDiv) and defer division until the final step, with explicit rounding policy. Ensure intermediate multiplication cannot overflow.
Fuzz amounts and prices around precision boundaries and compare the implementation with a high-precision reference formula. Assert the result does not lose an avoidable intermediate remainder.
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.