Beginner FriendlyFoundryDeFiOracle
100 EXP
View results
Submission Details
Severity: high
Invalid

You should not calculate the flash loan fee in terms of WETH since it is paid in the token that is borrowed. This leads to an incorrect calculation of the fee.

Summary

The flash loan fee is .3% of the amount of tokens borrowed, and you pay the fee in the token borrowed (and this setup works because every underlying token has its own AssetToken contract). But getCalculatedFee figures the fee in terms of WETH by multiplying the amount of tokens borrowed by the token's price in WETH. This isn't necessary given that you just need to multiply the amount of tokens borrowed times .003 (with appropriate adjustments for decimals) and, further, it actually results in an incorrect amount of fees. This might be necessary if fees were paid in ETH or if you were combining the returns of multiple tokens into one asset token, but that is not how the contract is configured.

Vulnerability Details

getCalculatedFee calculates the fee in terms of WETH:

function getCalculatedFee(
IERC20 token,
uint256 amount
) public view returns (uint256 fee) {
//slither-disable-next-line divide-before-multiply
uint256 valueOfBorrowedToken = (amount *
getPriceInWeth(address(token))) / s_feePrecision;
//slither-disable-next-line divide-before-multiply
fee = (valueOfBorrowedToken * s_flashLoanFee) / s_feePrecision;
}

Impact

Fees are being calculated incorrectly. Given that the depositors are paid based on fees, it is important to get the calculation right. Also, because the price of these tokens in terms of WETH is pretty low, you could end up with valueofBorrowedToken equaling less than 1 and being rounded down to 0, which would mean depositors would earn nothing for a flash loan and someone would get a free flash loan.

Tools Used

Manual review

Recommendations

Change the function as follows. Note that in another finding I recommended creating a mapping of token addresses to decimals to deal with tokens with different decimals and then calling that mapping for the precision decimals instead of one hard coded s_feePrecision but I did not reflect that here:

function getCalculatedFee(
IERC20 token,
uint256 amount
) public view returns (uint256 fee) {
return ((amount * s_flashLoanFee) / s_feePrecision);
}
Updates

Lead Judging Commences

0xnevi Lead Judge
over 1 year ago
0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Other

Support

FAQs

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