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

ERC20 with transfer's fee are not handled properly

Summary

The project is incompatible with fee on transfer tokens. If they are used some borrowers may be unable to repay his debt and get their collateral back

Vulnerability Details

Some ERC20 tokens may have fees attached to the transfer, while others could enable them in the future (e.g., USDT, USDC). The current implementation of Lender.sol is not taking these types of ERC20 tokens into consideration. Lender.sol assumes that the amount specified by the user will be the exact amount transferred to the contract's balance, whereas, in reality, the contract will receive less.

For instance, in the borrow function, the actual amount of collateral transferred to the contract is less than what is recorded in Loan struct

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
});

If borrower would like to get his collateral back he needs to call repay function which will try to transfer tokens:

// transfer the collateral tokens from the contract to the borrower
IERC20(loan.collateralToken).transfer(
loan.borrower,
loan.collateral
);

Because fees on transfer tokens are used, the contract was always receiving fewer funds than needed. If the borrower has a big enough debt, he will be unable to repay his debt.

Impact

Some borrowers may be unable to repay his debt and get their collateral back

Tools Used

Manual Review

Recommendations

Consider updating the Lender.sol logic to track the real amount of token that has been sent by the user after the transfer (difference in before and after balance)

Support

FAQs

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