We design a pretty easy contract game. Enjoy it! 1. Create a game account 2. Deploy a game contract 3. Request for flag 4. Get source code Option 1, get an account which will be used to deploy the contract; Before option 2, please transfer some eth to this account (for gas); Option 2, the robot will use the account to deploy the contract for the challenge; Option 3, use this option to obtain the flag when isSolved() function returns true; Option 4, use this option to get source code. You can finish this challenge in a lot of connections.
interface Storage { function getNumber() external view returns (uint256); }
contract Puzzle { Storage public Storage1; Storage public Storage2; Storage public Storage3;
bool public solved;
function check(bytes memory code) private returns(bool) { uint256 i = 0; while (i < code.length) { uint8 op = uint8(code[i]); if ( op == 0x3B || // EXTCODECOPY op == 0x3C || // EXTCODESIZE op == 0x3F || // EXTCODEHASH op == 0x54 || // SLOAD op == 0x55 || // SSTORE op == 0xF0 || // CREATE op == 0xF1 || // CALL op == 0xF2 || // CALLCODE op == 0xF4 || // DELEGATECALL op == 0xF5 || // CREATE2 op == 0xFA || // STATICCALL op == 0xFF// SELFDESTRUCT ) returnfalse;
i++; }
returntrue; }
function reverse(bytes memory a) private returns(bytes memory) { bytes memory b = new bytes(a.length); for (uint256 i = 0; i < a.length; i++) { b[b.length - i - 1] = a[i]; } return b; }
function sum(bytes memory a, bytes memory b) private returns(bytes memory) { bytes memory c = new bytes(a.length); for (uint256 i = 0; i < a.length; i++) { uint8 q = uint8(a[i]) + uint8(b[i]); c[i] = bytes1(q); } return c; }
data = "" data += "6001"# push 01 data += "6000"# push 00 data += "52"# mstore[0:0x20] = 1 data += "6020"# push 20 data += "6000"# push 00 data += "f3"# return
data += "f3"# return data += "0060"# push 00 data += "2060"# push 20 data += "52"# mstore[0:0x20] = 2 data += "0060"# push 00 data += "0260"# push 02
defcombine(x,y): x = bytes.fromhex(x) y = bytes.fromhex(y) result = [(a + b) & 0xfffor a,b inzip(x,y)] returnbytes(result).hex()
data = "" data += "30"# ADDRESS data += "6001"# push 01 data += "6000"# push 00 data += "52"# mstore[0:0x20] = 1 data += "6020"# push 20 data += "6000"# push 00 data += "f3"# return data += "00"# padding
data += "6003"# push 03 data += "6000"# push 00 data += "52"# mstore[0:0x20] = 3 data += "6020"# push 20 data += "6000"# push 00 data += "f3"# return
data += "00" * 10# padding
data += "00"# padding data += "f3"# return data += "0060"# push 00 data += "2060"# push 20 data += "52"# mstore[0:0x20] = 2 data += "0060"# push 00 data += "0260"# push 02 data += "3a"# GASPRICE
defcombine(x,y): x = bytes.fromhex(x) y = bytes.fromhex(y) result = [(a + b) for a,b inzip(x,y)] returnbytes(result).hex()
data = "" data += "30"# ADDRESS data += "6001"# push 01 data += "6000"# push 00 data += "52"# mstore[0:0x20] = 1 data += "6020"# push 20 data += "6000"# push 00 data += "f3"# return
data += "00"# padding data += "6000"# push 00
data += "6003"# push 03 data += "6000"# push 00 data += "52"# mstore[0:0x20] = 3 data += "6020"# push 20 data += "6000"# push 00 data += "f3"# return
data += "00" * 10# padding
data += "f3"# return data += "0060"# push 00 data += "03"# sub data += "4060"# push 40 data += "2060"# push 20 data += "52"# mstore[0:0x20] = 2 data += "0060"# push 00 data += "0260"# push 02 data += "3a"# GASPRICE
if check(data): print(data) # 30600160005260206000f3006000600360005260206000f300000000000000000000f30060034060206052006002603a
if check(reverse(data)): print(reverse(data)) # 3a600260005260206040036000f300000000000000000000f3006020605200600360006000f300602060520060016030
if check(combine(data,reverse(data))): print(combine(data,reverse(data))) # 6ac003c000a4c040c040f66060f3600360005260206000f3f3006020605200600360f36060f640c040c0a400c003c06a