Skip to content

0x963D/damn-vulnerable-defi-solutions

Repository files navigation

A set of challenges to learn offensive security of smart contracts in Ethereum.

Featuring flash loans, price oracles, governance, NFTs, lending pools, smart contract wallets, timelocks, and more!

Play

Visit damnvulnerabledefi.xyz

Disclaimer

All Solidity code, practices and patterns in this repository are DAMN VULNERABLE and for educational purposes only.

DO NOT USE IN PRODUCTION.

Damn Vulnerable DeFi Solutions

Solutions to Damn Vulnerable DeFi challenges ⛳️ < version v3.0.0 >

Contents

  1. Unstoppable
  2. Naive receiver
  3. Truster
  4. Side entrance
  5. The rewarder
  6. Selfie
  7. Compromised
  8. Puppet
  9. Puppet v2
  10. Free rider
  11. Backdoor
  12. Climber

1 - Unstoppable

The goal of the first challenge is to perform a DOS (Denial of Service) Exploit to the contract.

There is a suspicious line in the flashLoan function:

uint256 balanceBefore = totalAssets();

// totalAssets() returns the balance of the pool
asset.balanceOf(address(this));

If we can manage to alter the totalAssets() return, we will achieve the goal.

We can easily modify the asset.balanceOf(address(this)) by sending some token to the pool.

Test

2 - Naive receiver

In this challenge we have to drain all the funds from a contract made to call flash loans.

The contract expects to be called from the pool, which is fine, but the vulnerability lies on the fact that anyone can call the flash loan function of the pool.

In order to empty the contract in one transaction, we can create an Exploiter contract that calls the flash loan multiple times in its constructor, the repetitive 1 ETH fees draining the receiver in the process.

Test Exploit contract

3 - Truster

Here we have to get all the tokens from the pool, and our starter balance is 0.

The flashLoan from the pool lets us call any function in any contract. So, what we can do is:

  • Call the flashLoan with a function to approve the pool's tokens to be used by the Exploiter
  • Call the transferFrom function of the token, to transfer them to the Exploiter address

If we want to make it in one transaction, we can create a contract that calls the flashLoan with the approve, but instead of the Exploiter address, we set the created contract address. Then we transfer the tokens to the Exploiter in the same tx.

Test Exploit contract

4 - Side entrance

For this challenge we have to take all the ETH from the pool contract.

It has no function to receive ETH, other than the deposit, which is also the Exploit vector.

We can create an Exploiter contract that asks for a flash loan, and then deposit the borrowed ETH. The pool will believe that our balance is 1000 ETH, and that the flash loan was properly paid. Then we can withdraw it.

Test Exploit contract

5 - The rewarder

Here we have to claim rewards from a pool we shouldn't be able to.

Rewards are distributed when someone calls distributeRewards(), and depending on the amount of tokens deposited.

So, we can do all of this in one transaction:

  1. Wait five days (minimum period between rewards)
  2. Get a flash loan with a huge amount of tokens
  3. Deposit the tokens in the pool
  4. Distribute the rewards
  5. Withdraw the tokens from the pool
  6. Pay back the flash loan

Test Exploit contract

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published