4. Side Entrance
https://www.damnvulnerabledefi.xyz/challenges/side-entrance/
Last updated
https://www.damnvulnerabledefi.xyz/challenges/side-entrance/
Last updated
Objective
A surprisingly simple pool allows anyone to deposit ETH, and withdraw it at any point in time.
It has 1000 ETH in balance already, and is offering free flash loans using the deposited ETH to promote their system.
Starting with 1 ETH in balance, pass the challenge by taking all ETH from the pool.
Approach
flashLoan function checks the ETH balance of the contract via address(this).balance;
however, the balances could be accorded to different addresses as per the mapping balances
This means that ownership of the balances, as per balances
is not taken into account.
This can be achieved by nested a call to deposit()
within the external execute()
call
Solution
Since the lendingPool contract calls .execute
we need to create an attacker contract with such a function. The flash loan will be initiated from such a contract.
flashLoan is initiated with attack()
within the flash loan, execute is called on the caller contract (Attacker)
execute calls deposit -> this updates the balances mapping, incorrectly reflecting that the attacker has ETH balances of the flash loan amount
On returning the flashloan, the balances mapping remains incorrectly updated.
Attacker is able to withdraw ETH that did not originally belong to him, draining the contract
the fallback function is required to collect the ETH balances on withdrawal
without the fallback function, the sending of ether would revert
The tests in the foundry version checks that the attacker's wallet have received the ETH. Therefore we need to modify the attack contract to push out the ether recieved to msg.sender. Like so:
So we will add a call to transfer ether to msg.sender("attacker") within the attack() fn in Attacker Contract:
Please note that this is unsafe for production use as anyone can then call attack as it is an unguarded external function.
Proper process would dictate usinga onlyOwner modifier at least.