An attacker can steal any loan opening for auction by executing the Lender::buyLoan()
and specifying the poolId
parameter to a forged/fake pool. This vulnerability can even cause the protocol to become insolvent because an attacker moves out the stolen loans' loanToken
and/or collateralToken
tokens.
Root cause: the buyLoan()
lacks verification that the loan's loanToken
and collateralToken
must be identical to the new pool.
Therefore, an attacker can buy the loan using another pool of different loanToken
/collateralToken
pair.
To elaborate on this vulnerability, assume that a loan of 1 WETH (loanToken
) / 2000 USDC (collateralToken
) is opened for auction. An attacker can execute the buyLoan()
to buy the loan by pointing to a pool of DAI (loanToken
) / USDC (collateralToken
). In this way, the attacker can steal the loan's debt of $2000+ using small DAI tokens (totalDebt = 1 + lenderInterest + protocolInterest
).
Balance subtraction from a forged pool
: https://github.com/Cyfrin/2023-07-beedle/blob/658e046bda8b010a5b82d2d85e824f3823602d27/src/Lender.sol#L489
The attacker becomes a new lender
: https://github.com/Cyfrin/2023-07-beedle/blob/658e046bda8b010a5b82d2d85e824f3823602d27/src/Lender.sol#L518
An attacker can steal any loan opening for auction by executing the buyLoan()
and specifying the poolId
parameter to a forged pool. The forged pool can even point to a pair of fake loanToken
and collateralToken
, which has worth $0.
This vulnerability can even cause the protocol to become insolvent because an attacker moves out the stolen loans' loanToken
and/or collateralToken
tokens. Hence, I consider this vulnerability a high-risk issue.
Manual Review
I recommend verifying that the loan's loanToken
and collateralToken
must be identical to the new pool, as shown below.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.