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

the protocolis not compatible to work with other decimals than 18 deciamls

Summary

Using tokens lower or higher than 18 decimals can lead to the wrong loan ratio.

Vulnerability Details

borrow() function checks the loan ratio to avoid users borrowing too much than collateral. but the issue is the calculation of the loan ratio only works correctly with 18 decimal tokens and if the user uses tokens like USDT which is 6 decimals can lead to wrong calculation and as a result, lead to borrowing less or more than the true ratio.

function borrow(Borrow[] calldata borrows) public {
for (uint256 i = 0; i < borrows.length; i++) {
bytes32 poolId = borrows[i].poolId;
uint256 debt = borrows[i].debt;
uint256 collateral = borrows[i].collateral;
// get the pool info
Pool memory pool = pools[poolId];
// make sure the pool exists
if (pool.lender == address(0)) revert PoolConfig();
// validate the loan
if (debt < pool.minLoanSize) revert LoanTooSmall();
if (debt > pool.poolBalance) revert LoanTooLarge();
if (collateral == 0) revert ZeroCollateral();
// make sure the user isn't borrowing too much
uint256 loanRatio = (debt * 10 ** 18) / collateral;
if (loanRatio > pool.maxLoanRatio) revert RatioTooHigh();
// create the loan
Loan memory loan = Loan({
lender: pool.lender,
borrower: msg.sender,
loanToken: pool.loanToken,
collateralToken: pool.collateralToken,
debt: debt,
collateral: collateral,
interestRate: pool.interestRate,
startTimestamp: block.timestamp,
auctionStartTimestamp: type(uint256).max,
auctionLength: pool.auctionLength
});
// update the pool balance
_updatePoolBalance(poolId, pools[poolId].poolBalance - debt);
pools[poolId].outstandingLoans += debt;
// calculate the fees
uint256 fees = (debt * borrowerFee) / 10000;
// transfer fees
IERC20(loan.loanToken).transfer(feeReceiver, fees);
// transfer the loan tokens from the pool to the borrower
IERC20(loan.loanToken).transfer(msg.sender, debt - fees);
// transfer the collateral tokens from the borrower to the contract
IERC20(loan.collateralToken).transferFrom(
msg.sender,
address(this),
collateral
);
loans.push(loan);
emit Borrowed(
msg.sender,
pool.lender,
loans.length - 1,
debt,
collateral,
pool.interestRate,
block.timestamp
);
}
}

Impact

Using tokens other 18 than decimal can lead to the wrong calculation of loanRatio so as a result user borrow more or less than the true ratio.

Tools Used

Manual Review

Recommendations

Consider get token decimals by interface and implement calculation for avoid this issue.

Support

FAQs

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