This was just me getting used to hackmd. Cant find delete button lol
will be grabbed from rever.etk using vm.ffi and ./script/compile.sh
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
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)
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
// 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");
}
}