Severity: Medium · Impact: Medium · Likelihood: Medium
The token compatibility list explicitly includes fee-on-transfer tokens (STA, PAXG, and USDT which can enable a transfer fee). flashloan() measures repayment purely by the AssetToken's balance: it records startingBalance and requires endingBalance >= startingBalance + fee.
When the borrowed token charges a transfer fee, a borrower who correctly sends amount + fee via repay() causes the AssetToken to receive less than that (the fee is deducted in transit), so endingBalance never reaches startingBalance + fee and the loan reverts.
Likelihood:
Occurs for every flash loan of an in-scope fee-on-transfer token, even when the borrower behaves honestly and repays the full amount + fee.
Impact:
Flash loans of these supported tokens are impossible (a core feature is bricked for a whole class of in-scope assets). The same undercounting also corrupts deposit() accounting, so LP balances for such tokens overstate the real holdings.
Save the block below as test/PocM2.t.sol and run forge test --mt test_flashloan_reverts_for_fee_on_transfer_token -vv. An honest flash loan that repays amount + fee reverts because the token deducts a transfer fee.
Do not assume the token is standard. Either (a) restrict the protocol to a vetted allow-list of non-fee, non-rebasing tokens and document it, or (b) make the accounting balance-based so it tolerates transfer fees — measure the AssetToken's real balance before and after and require the delta to cover the fee, rather than assuming amount + fee arrives intact.
Prefer approach (a) — a strict allow-list — as the robust fix, since balance-delta accounting still cannot make fee-on-transfer economics work for the borrower.
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.