# Rever *This was just me getting used to hackmd. Cant find delete button lol* ## You send runtime bytecode to setup.challenge().deploy() will be grabbed from rever.etk using vm.ffi and ./script/compile.sh ## Example inputs find string through `cast --format-bytes32-string <string>` or https://www.rapidtables.com/convert/number/ascii-to-hex.html "paradigm" 70 61 72 61 64 69 67 6d ... 00000000000000 p a r a d i g m ... 0000000000 "tattarrattat" 0x7461747461727261747461740000000000000000000000000000000000000000 ### Useful opcodes calldataload loads 32bytes of calldata following your stack input [offset] calldatasize size of string msize (before allocating) 0 chainid (on mainnet) 1 selfbalance *ANY* just need to transfer in amount byte can isolate bytes to check equality inputs [i, word] i as 0 is most sig byte (left), i as 31 is least sig byte (right) ### Solving ```etk runtimeBytecode: # your runtime bytecode # we need this to be less than 51 bytes so that we can palindrome it # initialize word - this stack item needs to be here for the entire puzzle msize # this is 0 at the moment calldataload # this is the string NOT abi encoded # word_start is always 0 msize # initialize word_end (calldatasize - 1) chainid calldatasize # this is length of string - only needed to set up word_end sub # initialize loop counter msize # exit conditions are either byte eq fails (false) or word_start >= word_end (true) # enter loop with [loopCount, word_end, word_start, word] loop: jumpdest # [loopCount, word_end, word_start, word] # dec cur_end dup1 dup3 # [word_end, loopCount, loopCount, word_end, word_start, word] sub # [cur_end, loopCount, word_end, word_start, word] # inc cur_start dup4 dup3 add # [cur_start, cur_end, loopCount, word_end, word_start, word] # check if palindrome is finished dup2 dup2 # [cur_start, cur_end, cur_start, cur_end, loopCount, word_end, word_start, word] lt # [start<end, cur_start, cur_end, loopCount, word_end, word_start, word] iszero # [start>=end, cur_start, cur_end, loopCount, word_end, word_start, word] push1 win jumpi # [cur_start, cur_end, loopCount, word_end, word_start, word] # get word_start byte dup6 # [word, cur_start, cur_end, loopCount, word_end, word_start, word] swap1 # [cur_start, word, cur_end, loopCount, word_end, word_start, word] byte # [start_byte, cur_end, loopCount, word_end, word_start, word] # get word_end byte swap1 # [cur_end, start_byte, loopCount, word_end, word_start, word] dup6 # [word, cur_end, start_byte, loopCount, word_end, word_start, word] swap1 # [cur_end, word, start_byte, loopCount, word_end, word_start, word] byte # [end_byte, start_byte, loopCount, word_end, word_start, word] # check if bytes are not equal eq # [equal, loopCount, word_end, word_start, word] iszero # [!equal, loopCount, word_end, word_start, word] push1 lose jumpi # jump if lost # otherwise: increment loop counter, rearrange stack and continue # [loopCount, word_end, word_start, word] chainid add # [loopCount+1, word_end, word_start, word] push1 loop jump lose: jumpdest chainid selfbalance return # return false, no palindrome win: jumpdest chainid selfbalance mstore8 chainid selfbalance return # return true, palindrome # 593559463603595b80820383820181811015602a5785901a9085901a141560265746016007565b4647f35b4647534647f3 # 49 bytes, just under the limit ``` ```solidity // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; import "forge-std/Test.sol"; import "../src/rever/public/contracts/Setup.sol"; contract ATest is Test { Setup setup; bytes etkCode; function setUp() public { setup = new Setup(); string[] memory inputs = new string[](2); /** * windows: scripts/compile.bat * linux : scripts/compile.sh */ inputs[0] = "./script/compile.sh"; // path/to/contract.etk // Need to palindrome this before solving fr, tho fwd works inputs[1] = "./src/rever/public/contracts/rever.etk"; etkCode = vm.ffi(inputs); } function testRever() public { Challenge challenge = setup.challenge(); challenge.deploy(etkCode); console2.logBytes(challenge.fwd().code); console2.logBytes(challenge.rev().code); setup.test("1aba1"); setup.test("2a2"); setup.test("3abababa3"); setup.test("a"); setup.test("paradigm"); } } ```