20,000 USDC
View results
Submission Details
Severity: medium

Malicious Lender can steal Billions of Funds in Tokens without paying a penny if transferFrom returns boolean on failure

Summary

Malicious Lenders can drain almost all the funds of the contract without paying any collateral to the contract.

Vulnerability Details

While calling the addToPool function,
The entire mapping is in hands of the Caller/Lender .
He can easily craft such an array which meets all the requirements

-> msg.sender is p.lender , which he is
-> amount is non-zero

And as we can see in the code

function addToPool(bytes32 poolId, uint256 amount) external {
if (pools[poolId].lender != msg.sender) revert Unauthorized();
if (amount == 0) revert PoolConfig();
-> _updatePoolBalance(poolId, pools[poolId].poolBalance + amount);
// transfer the loan tokens from the lender to the contract
-> IERC20(pools[poolId].loanToken).transferFrom(
msg.sender,
address(this),
amount
);
}

The contract updates the balances first and then try to pull amount tokens from Lender( msg.sender).

If the token implements returning false on failure to transfer tokens instead of reverting altogether,
The contract will be in serious trouble.

Exploit Scenario

-> Let's say some pool has 20 Billion x tokens and the transferFrom of x token returns false on failure instead of reverting. The contract has these tokens now !

-> An attacker makes a pool containing x token in it.
initially, he deposits like 10 tokens.

-> Now he calls the addToPool function using parameters (his_pool_id,20 Billion ).

-> The contract updates the balance of pool to contain 20 Billion x tokens.

-> It tries to transfer 20 Billion from lender and fails but just returns false not reverts.

-> The Attacker calls removeFromPool function and remove the 20 Billion x tokens.

HACKED !!!

Impact

-> Monetary Loss
-> Loss of User's Trust in Protocol

Tools Used

Manual Review,

Recommendations

Check
-> Return values of transferFrom
-> the balance of the contract after the transfer

and update the balance only when the contract has pulled enough tokens in addToPool function

Support

FAQs

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

Give us feedback!