The next puzzle in the series continues challenging players to empty DeFi lending pool through any means necessary. Here is the challenge:
A surprisingly simple lending pool allows anyone to deposit ETH, and withdraw it at any point in time.This very simple lending pool has 1000 ETH in balance already, and is offering free flash loans using the deposited ETH to promote their system.You must steal all ETH from the lending pool.
The challenge.js file performs basic setup on the vulnerable pool contract and deposits some initial balance:
Let’s take a look at the SideEntranceLenderPool contract to see if we can spot any vulnerabilities:
The contract implements a simple flashLoan() function which issues arbitrary amount to whoever triggers it and makes sure that the total contract balance remains the same or greater after it completes. Just like other lending functions, it also executes a 3rd party logic in order to do useful work with borrowed funds:
A quick look at the flash loan repayment logic reveals a vulnerability where the contract only cares about the total contract value and not their ownership. So if an attacker borrowed some funds and immediately deposited them back to the contract, it would appear as if all of the borrowed funds even though the attacker has claimed their ownership.
Let’s craft a sample attack contract which implements execute() callback used by the flashLoan() function which borrows the entire contents of the pool and immediately deposits it back. A separate attack() function can then be used to withdraw the newly claimed funds and send them back to whoever runs it:
Finally, let’s modify the challenge.js file to deploy the AttackerSideEntrance contract and execute it:
Running the above will exploit the weakness described above and completely empty the lending pool:
And we successfully passed the challenge!