# Unsafe implementation of fundLoan() allows attacker to steal collateral from an unfunded loan

fundLoan() trusts caller-supplied lender contract for fee/treasury addresses, letting attacker zero out drawable funds and repossess borrower collateral.

- Payout: Audit contest
- Severity: medium
- Program: Maple Finance
- Found by: WatchPug
- Disclosed: 2022-01-05
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2021-12-maple-findings/issues/47
- Library page: https://bugbountylibrary.com/r/c4%3A2021-12-maple%3AM-02
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic vuln:flash-loan

**Target:** MapleLoanInternals.sol fundLoan() / loan contract
**Root cause:** fundLoan() reads treasuryFee, investorFee, mapleTreasury and poolDelegate from the caller-supplied lender_ address without verifying it is a legitimate pool, so a fake lender can set fees near 100%.
**Steps:**
1. Borrower posts collateral via `postCollateral()` (e.g. 10 BTC) for a principal request of 1,000,000 USDC.
2. Attacker flash-loans 1,000,000 USDC and calls `fundLoan()` passing a fake `lender_` contract whose `treasuryFee()`/`investorFee()` return huge values and whose `mapleTreasury()`/`poolDelegate()` return attacker addresses.
3. Fees computed from fundsLent_ * fee * interval * payments / (365 days * 10000) nearly equal fundsLent_, so `_drawableFunds` ≈ 0; fee transfers route back to attacker.
4. Borrower's `drawdownFunds()` reverts (nothing drawable) and `removeCollateral()` reverts with `MLI:DF:INSUFFICIENT_COLLATERAL`.
5. After grace period (~2 days) attacker calls `repossess()` and takes the 10 BTC collateral.
**How found:** Code review of fundLoan(): noticed treasuryFee/investorFee/mapleTreasury/poolDelegate are all read from the untrusted lender_ parameter, then reasoned that a fake lender could set fees to drain drawable funds and trigger repossession.
**Exploitation:** Attacker flash-loans the principal, funds the loan through a malicious ILenderLike contract that inflates fees and redirects fee transfers to itself, leaving the borrower with zero drawable funds and locked collateral, then repossesses the collateral after the grace period.
**Insight:** When a function pulls fee rates and payout addresses from a caller-supplied contract address, check whether that address is authenticated against a registry; unauthenticated lender/pool params let you set fees to ~100% and redirect them to yourself.
