I'm trying to follow this tutorial: https://dev.to/nvn/ethernaut-hacks-level-23-dex-two-4424

I have a few questions:

  1. There are three addresses (DexTwo, player, and EvilToken). I understand EvilToken is another contract address created by the attacker, but what is the difference between the DexTwo and player address?

We're going to exchange EVL token for token1 and token2 in such a way to drain both from DexTwo. Initially both token1 and token2 is 100. Let's send 100 of EVL to DexTwo using EvilToken's transfer. So, that price ratio in DexTwo between EVL and token1 is 1:1. Same ratio goes for token2.

  1. What is the rationale for the design of this approach (above)?

Also, allow DexTwo to transact 300 (100 for token1 and 200 for token2 exchange) of our EVL tokens so that it can swap EVL tokens. This can be done by approve method of EvilToken, passing contract.address and 200 as params.

  1. Why transact 300 EVL tokens to allow DexTwo to swap EVL tokens as discussed (above)?

Swap 100 of player's EVL with token1: await contract.swap(evlToken, t1, 100)

  1. Why does swapping 100 of player's EVL with token1 can drain all of token1 from DexTwo (above)?

Any help is appreciated. Thank you.

1 Answer 1


This challenge is on input checking, the DEX contract is supposed to trade between token1 and token2. However, it forgot to check which tokens are from and to in its swap(address from, address to, uint amount) function. It leads to the attacker using a fake token (e.g. worthless token EvilToken (EVL) created by the attacker) to trade with the legit token1 token2.

In real-life analogy: DEX is supposed to trade between USD and EUR which has real value, but they forgot to check whether the things they trade are real USD EUR, so some attackers use fake money (e.g. FakeUSD printed by him) to trade with the real USD and EUR to drain all of DEX's real money and left DEX with all fakeUSD.

  1. The DEX is the exchange the service that holds some real token with value token1 and token2 in their reserve. The player is some random user with some small amount of token1 and token2 trying to break the DEX, so the player mints their own fake token EVL and fools the DEX to trade real tokens with fake ones.
  2. They send the same amount of EVL 100 to DEX compared to what DEX's holds for each token to make the price predictable (exchange 1:1) for the next trade. It's because of the way how DEX calculates the exchange rate: get_swap_amount(), if DEX has 100 EVL and 100 token1, the exchange price will be 1:1. You can call this the setup step for token 1.
  3. Because of the above step, the exchange rate now is 1:1. The action in this question 3 is what they use 100 EVL to get 100 token1 (the objective of the challenge).
  4. After step3 Dex now has 200 EVL because you just sent it to DEX to drain 100 token1. Because Dex has 200 EVL and 100 token2, the exchange rate now is 2 EVL for 1 token2. So to drain the remaining 100 token2 (the objective), you have to send in 200 EVL. That explains your question 3 (need 100 for token1 and 200 for token2 because the exchange rate changed after you drained token1).

This scenario is unrealistic in real DEX, but it's a good challenge for learning how a simple DEX swaps tokens and calculates simple exchange rate at a basic and insecure way. Hope this helps.

  • The tutorial said "allow DexTwo to transact 300 (100 for token1 and 200 for token2 exchange)" and in the table the player now has 300 EVL, where did the 300 EVL tokens come from? Jan 6, 2023 at 6:08
  • the 300 EVL comes from the step deploying EvilToken with initial supply of 400. Basically, you deploy the EvilToken contract with argument initialSupply=400, this one will be executed when you deploy constructor(uint256 initialSupply)
    – minhhn2910
    Jan 6, 2023 at 6:49
  • After deploying as the above, the player (the one who deploy EvilToken ) contract will have 400 EVL to spend. The player then deposits 100 EVL to DEX to set the exchange rate 1:1, then the player spends 100 EVL to get 100 token1 and the remaining 200 EVL to get 100 token2 like I described above
    – minhhn2910
    Jan 6, 2023 at 6:50
  • I'm still confused on this part: The tutorial said "allow DexTwo to transact 300 (100 for token1 and 200 for token2 exchange)" and in the table the player now has 300 EVL, what does approving DexTwo to transact 300 EVL tokens have anything to do with the player now having 300 EVL? Jan 6, 2023 at 21:10
  • 1
    That means allowing DexTwo contract to spend the player's EVL` token, you can allow more than 300, can even allow 1Billions tokens, it doesn't matter. It is the mechanism for contract to transfer ERC20 token on behalf of user via approve function. Affter player approve DexTwo, the DexTwo contract now can call transferFrom to transfer player's token to anyone. It's quite long to explain here in details, you can read it online, for example : brogna.medium.com/token-allowance-dc553f7d38b3
    – minhhn2910
    Jan 7, 2023 at 6:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.