Damn Vulnerable DeFi — Challenge #2 Walkthrough

Continuing our exploration of the Damn Vulnerable DeFi wargame, the next puzzle is called Naive receiver. It challenges players to drain a DeFi user’s account:

There's a lending pool offering quite expensive flash loans of Ether, which has 1000 ETH in balance.You also see that a user has deployed a contract with 10 ETH in balance, capable of interacting with the lending pool and receiveing flash loans of ETH.Drain all ETH funds from the user's contract. Doing it in a single transaction is a big plus ;)

The challenge file sets up a lending pool and a user receiver contracts. The receiver contract is configured with the lending pool address so that it could interact with it:

The target of the contract which we need to empty is stored at . It is deployed using contract which includes on interesting function capable of reducing user’s wallet:

In the above snippet, accepts an arbitrarily sized fee and sends it to the pool address along with the borrowed amount. Note that the function verifies to match the pool address to make sure that we can’t just call it directly and drain all of the funds. Ok, let’s work with the contract and see if we can trigger somehow:

This looks promising! can be called by anyone and calls on the target borrower contract with an arbitrary loan amount. Unfortunately, the fee is hard-coded to just 1 ETH, so we will need to trigger this function as many times as necessary until the borrower account is completely drained due to fees.

Below is a simple while loop that will keep on calling on the until the balance of user’s contract is completely empty:

Let’s test the above loop and see if we can solve the challenge:

Success! The is drained and the challenge is solved. Or is it? Note that the last line of the challenge assignment:

Drain all ETH funds from the user's contract. Doing it in a single transaction is a big plus ;)

The above solution will generate 10 unique Ethereum transactions so it’s not an ideal path. In order to get our job done in a single transaction we will need to use a utility contract. Let’s call it and place it in the directory with the following code:

The above contract implements a single function which essentially executes the same logic as we did before except in Solidity. Modify the challenge file as follows in order to import and call :

At last, rerun the challenge file:

Great! We have successfully drained user’s funds while doing a single transaction to our attack contract.

References

Blockchain Security, Malware Analysis, Incident Response, Pentesting, BlockThreat.net

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store