Suppose we have a pool1 with pair of token1(loan token) and token2(collateral token):
token2
is a type of token that does not revert when insufficient tokens are present, instead returns a false
value.
The lender of the pair creates a pool with 1000
loan tokens and the borrower borrows all of the loan tokens by depositing collateral tokens inside the Lending
contract.
Attack starts:
The attacker saw that there is a pool whose collateral token is a type of token which do not revert on insufficient tokens.
He created a pool2 with pair of token1(collateral token of pair1 as loan token) and token2(any other token)
He can create a pool with max uint256
value of pool balance (without approving to contract because it does not check return value). He can also increase using addToPool
if he sees this opportunity later.
Now he can remove the token from his pool using removeFromPool
and get the token1 out of the contract (which were not his pool funds instead there were the collateral funds of the other pools stored in the lending
contract)
A contract only has 1000 collateral tokens which were removed by malicious lender now when a borrower tries to repay and get his funds then he will see a contract out of funds error.
There are many other places where the return value is not checked in the codebase but they do not risk the funds directly, but these two points (setPool
and addToPool
) do.
Others' deposited collateral funds will be stolen by a malicious lender.
Manual Review
Use the SafeERC20 library implementation from OpenZeppelin and call safeTransfer or safeTransferFrom when transferring ERC20 tokens.
If you do not want to use it on all places then atleast use it on these 2 places.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.