King
1. 题目要求
1.1 题目:下面的合约表示了一个很简单的游戏:
任何一个发送了高于目前价格的人将成为新的国王. 在这个情况下, 上一个国王将会获得新的出价, 这样可以赚得一些以太币. 看起来像是庞氏骗局.这么有趣的游戏, 你的目标是攻破他, 当你提交实例给关卡时, 关卡会重新申明王位. 你需要阻止他重获王位来通过这一关.
1.2 题目代码:
1 | // SPDX-License-Identifier: MIT |
2. 分析
tips:参考博客
2.1 阅读代码可知,该
receive
函数是一个特殊函数,允许合约直接从外部合约或 EOA 接收以太币2.2 我们首先看到的是
require(msg.value >= prize || msg.sender == owner)
。此检查允许owner
合约的 始终拥有合约的王权,重置所有值。2.3 所以现在我们知道
transfer
允许您将 Ether 发送到一个地址,消耗2300
gas 并在无法执行交易时恢复。如果“将以太币转移到”交易恢复,为什么会出现问题?好吧,因为如果还原,我们的功能
transfer
也会还原!并且通过还原它会使合约无法使用,没有人可以成为新的国王!receive
一种可能的解决方案是只创建一个
Contract
不接受任何类型的 Ether 转移的对象。2.4 攻击合约
1 | contract Exploiter { |
- 2.5 获取实例地址,并填入到Exploiter合约构造器中
3. 解题
3.1 获取关卡实例地址:0x25766108F8Fa65C8061FB17E7762D4BC42Fc882C
3.2 调用关卡实例部署的合约,得到实例合约中的prize
3.3 根据关卡实例地址部署攻击合约
3.4 Deploy后查看king的值发生了改变
3.5 提交实例
3.6 成功!!!!!