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

the protocol lose money on when users use fee on transfer token for collateral

Summary

the protocol lose money on when users use fee on transfer token for collateral

Vulnerability Details

the protocol is not compatible with Fee-On-Transfer tokens thus this will cause the protocol lose some funds.
how?:

let us look at the borrow function this function gets collateral when the borrower wants to get the loan so collateral transfers to the contract and the contract stores the data of the loan. but the problem is when the contract actually transfers the fee on the transfer token the final amount that is in the contract is less than what it settled before in inputs, so this will cause the contract for e.g store 100% of the amount but actually get 95% of tokens and when user wants to repay the loan and get the collateral the contract will transfer 100%, yes 5% more than what it actually suppose to transfer and will lose money on that part.

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

the
protocol will lose some funds.

Tools Used

manually

Recommendations

there is two ways of preventing this issue

  • consider implementing the logic for Fee on transfer tokens

  • consider not supporting fee on transfer tokens

Support

FAQs

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