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

Some ERC20 tokens would revert on zero value fee transfers.

Summary

Functions like repay would fail if the fees calculated using _calculateInterest within these functions return a 0 value.

Vulnerability Details

Note that the protocol does not limit what type of tokens will be used. As anyone can create a pool with any ERC20 token.
Some tokens like LEND revert on zero-value fee transfers. So, if fees generated within _calculateInterest is 0, then the following would revert for tokens like LEND:

IERC20(loan.loanToken).transferFrom(
msg.sender,
feeReceiver,
protocolInterest
);

where protocolInterest is the following:

(
uint256 lenderInterest,
uint256 protocolInterest
) = _calculateInterest(loan);

It is generated from the _calculateInterest. Since the transfer is done within the repay function, the repay function would revert.

The following POC was tested using Fuzz-testing.

function testFuzzZeroFees(uint256 debt, uint256 time, uint256 rate) public {
//Note - this lower bound for interest rate is possible,
//cause the setPool function only checks for the upper bound.
rate = bound(rate, 10, 100000);
time = bound(time, 100, 30 days); //the lower bound could be even lower for time.
//Note - the lower bound could be even lower. Depends on the minLoanSize of the pool.
//Theoretically, even lower bounds are possible.
debt = bound(debt, 10 ** 8, 10 ** 18);
uint256 feePercent = 1000; //lenderFee percent
//Note - this is a simplified version of _calculateInterest function.
uint256 interest = (rate * debt * time) / 10000 / 365 days;
uint256 fees1 = (interest * feePercent) / 10000;
console.log("rate: ", rate);
console.log("feePercent: ", feePercent);
console.log("debt: ", debt);
console.log("time: ", time);
console.log("fees1: ", fees1);
//Note - the following assertion fails.
assertTrue(fees1 != 0);
}

The assertion always failed. The console logs:

Logs:
Bound Result 10
Bound Result 100
Bound Result 100000000
rate: 10
feePercent: 1000
debt: 100000000
time: 100
fees1: 0
Error: Assertion Failed

Impact

If the fee returned is 0, then a function like repay would fail when they try to send a 0 value token transfer, for tokens like LEND.

Tools Used

Fuzz-testing, manual review

Recommendations

Ensure the following:

if(protocolInterest > 0) {
IERC20(loan.loanToken).transferFrom(
msg.sender,
feeReceiver,
protocolInterest
);
}

Support

FAQs

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

Give us feedback!