A flash-loan fee paid in the borrowed asset should be calculated as a percentage of the borrowed asset amount. For example, at a 0.3% fee, borrowing 1 token requires repaying 1.003 tokens, independent of that token’s WETH price.
getCalculatedFee() first converts the borrowed amount into WETH value, then returns that WETH-denominated result as fee. flashloan() subsequently treats this value as an amount of the borrowed token and requires repayment in that token. Consequently, every asset whose price differs from exactly 1 WETH is charged an incorrect fee.
Likelihood:
Every flash loan of a supported token priced above or below 1 WETH uses an incorrectly denominated fee.
Assets such as stablecoins, WBTC, and other non-WETH assets naturally have prices and decimal conventions that differ from WETH.
Impact:
Borrowers of assets priced below 1 WETH pay less than the intended percentage fee, reducing or eliminating LP yield.
Borrowers of assets priced above 1 WETH are overcharged, potentially making flash loans unavailable; non-18-decimal assets can be charged by orders of magnitude incorrectly.
The following test demonstrates that a token worth 0.1 WETH is charged 0.0003 tokens for borrowing 1 token, instead of the intended 0.003 tokens.
Add this to [`test/unit/ThunderLoanTest.t.sol`](/home/jpn/code/defi/ai_auditing/2023-11-Thunder-Loan/test/unit/ThunderLoanTest.t.sol):
For a token worth 2 WETH, the opposite occurs: the protocol collects 0.006 tokens for a 1 token loan, double the intended 0.3% fee.
Since repayment occurs in the borrowed token, calculate the fee directly from the borrowed token amount:
Remove the oracle from fee calculation. An oracle is only needed when fees are intentionally charged in a different asset, such as WETH; in that design, collect WETH separately rather than treating a WETH amount as an underlying-token amount.
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.