Dex Two
1. 题目要求
1.1 This level will ask you to break
DexTwo
, a subtlely modifiedDex
contract from the previous level, in a different way.You need to drain all balances of token1 and token2 from the
DexTwo
contract to succeed in this level.You will still start with 10 tokens of
token1
and 10 oftoken2
. The DEX contract still starts with 100 of each token.Things that might help:
题目代码
1 | // SPDX-License-Identifier: MIT |
2. 分析
tips:参考博客
2.1 分析合约:
swap
函数 :
1 | function swap( |
当前
swap
函数不检查from
,实际上是合约处理的to
白名单token1
和代币。token2``DexTwo
这是该函数先前版本中存在的检查:
require((from == token1 && to == token2) || (from == token2 && to == token1), "Invalid tokens");
这是什么意思?这允许攻击者调用该
swap
函数,出售任意 令牌以从 Dexfrom
获取“真实”令牌。to
这意味着我们可以创建一个UselessERC20
完全由我们拥有和管理的全新代币(我们可以铸造、销毁、做任何我们想做的事)并获得一些token1
或token2
免费获得。我们可以耗尽
DexTwo
合同token1
并token2
各打一次电话吗?为此,我们需要找到正确的fakeToken
卖出数量以取回 100token1
。做数学计算,看一下getSwapAmount函数
100 token1 = amountOfFakeTokenToSell * DexBalanceOfToken1 / DexBalanceOfFakeToken 100 token1 = amountOfFakeTokenToSell * 100 / DexBalanceOfFakeToken
1
2
3
4
5
6
- 我们有两个可以控制的变量。我们肯定知道它`DexBalanceOfFakeToken`必须**> 1**否则交易将因为被**0 除**而恢复。如果我们发送 1`FakeToken`给`DexTwo`我们
- > ```unknown
100 token1 = amountOfFakeTokenToSell * 100 / 1
1 token1 = amountOfFakeTokenToSell因此,通过
1 FakeToken1
向DexTwo
合约发送给它一些流动性,我们可以交换 100FakeToken
以取回 100token1
。之后,我们只需要对另一个实例重复相同的操作,并从 Dex 中FakeToken2
排出所有的。token2
攻击合约
1 | function exploitLevel() internal override { |