20,000 USDC
View results
Submission Details
Severity: high
Valid

`loanRatio` insufficiently expressive for some combinations of tokens

Summary

loanRatio is calculated with 18 decimals of precision, which truncates the expressible LTV space if the debt token has too few decimals.

Vulnerability Details

Lender.sol has the concept of the "loan ratio": the ratio of debt to collateral, more commonly known as a loan-to-value (LTV) ratio. Pools contain a maxLoanRatio parameter that dictates the maximum amount of loan token a borrower can borrow against their collateral. The loan ratio is calculated as follows:

uint256 loanRatio = (debt * 10 ** 18) / collateral

Some notable tokens like GUSD (Top 100) and EURS (Top 300) have 2 decimals. If GUSD is used as the loan token, then the range expressible by loanRatio is 1 GUSD <= 100 COLLTOKEN, where COLLTOKEN has 18 decimals.

Consider now that COLLTOKEN is a high-supply token such as SHIB (Top 20) which has a value of $0.000001. Then loanRatio cannot express a meaningful loan-to-value ratio at current market price. If the lender sets pool.maxLoanRatio=1, the minimum acceptable value, then borrowers will still be able to borrow up to 10000x the dollar amount in SHIB per 1 GUSD.

Impact

Impact is critical: certain pools can be drained, however likelihood is quite low because a few prerequisites must be in place:

  • Lender creates a pool with GUSD as the loan token and an 18-decimal token as the collateral token.

  • The market rate of the collateral token drops below $0.01 and the lender does not react in time by removing pool liquidity.

  • Arbitrageurs can atomically obtain COLLTOKEN, borrow all GUSD and sell it for a profit.

Tools Used

Manual Review, foundry

Recommendations

Change the precision factor to 10**27 in the calculation:
uint256 loanRatio = (debt * 10 ** 27) / collateral;

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.