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

Fee on Transfer tokens

Summary

Fee on transfer tokens make project not to work as expected

Vulnerability Details

Certain fee on transfer tokens take a fee when they are transferred. This may result in project expecting x tokens but actually receiving x-a tokens where a is a fee. This impacts logic parts of contract as actual balances transferred to the contract are not what is recorded in the state or state changes

  1. Besides that above leads to

  • faulty accounting,

  • reverts( e.g Lender.sol line 232 function borrow() a borrower expecting pool balance = x; when in actual fact amount in protocol is x-a; tries to borrow x line 269 IERC20(loan.loanToken).transfer(msg.sender, debt - fees);may fail as amount in protocol not sufficient,

  • when trying to transfer funds as amounts available less than specified, protocol and users receiving less funds than expected

  1. Pools can be drained of funds, see setPool() Lender.sol from line 230 for example //assume 10% fee token

  • lender sets up first time pool with p.balance = 10, actual amount = 9 deposited into protocol

  • lender calls setPool again with p.balance = 9 //actual that would come in is 9*0.9 = 0.81

  • since Lender.sol line 157--->
    else if (p.poolBalance [9 ] < currentBalance [10] ) {
    // if new balance < current balance then transfer the difference back to the lender
    IERC20(p.loanToken).transfer(
    p.lender,
    currentBalance - p.poolBalance [10-9 = 1 token back]
    );

  • however lender was actually supposed to receive based on actual token balances accounting in pool [9-8.1 = 0.9] transferred back but 1 token is sent back meaning 1-0.9 = 0.1 is being taken from other pools if there exist other pools with poolToken else since funds no enough there many be a revert

Impact

Medium : Protocol will not work as expected

Tools Used

Manual Analysis

Recommendations

It is recommended they are not allowed by implementing a whitelist of allowable tokens
It is recommended in functions to verify amounts that came into protocol and revert if not similar to accounting or account based on this actual values e. g as in below
function x() {
amountBefore = IERC20(feeTokenTransferredIn).balanceOf(address(this));
.......transfer in token from caller
amountAfter = IERC20(feeTokenTransferredIn).balanceOf(address(this));
amountDeposited = amountAfter - amoutnBefore
/// armed with amountDeposited you can now use this in your logic instead of assuming amount x was transferred in when in actual fact x-fee was transferred in

Support

FAQs

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