1/// @title Antikythera2/// @author @vex_0x3/// @dev My damn Antikythera's busted again.4
5#include "huffmate/utils/Shuffling.huff"6
7////////////////////////////////////////////////////////////////8// INTERFACE //9////////////////////////////////////////////////////////////////10
11/// @notice Returns the name of the puzzle12#define function name() view returns (string memory)13/// @notice Verifies that a solution is valid for the puzzle14#define function verify(uint256 _start, uint256 _solution) nonpayable returns (bool)15/// @notice Generates the puzzle's starting position based on a seed.16#define function generate(address _seed) view returns (uint256)17
18/// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿19/// ⣿⣿⣿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⢿⣿⣿⣿⣿⣟⠋⣿⣿⣿⣿⣿⣿⣿⣿⣿20/// ⣿⣿⣷⣤⣿⣿⣿⣿⣿⣿⣿⣭⣁⠀⠀⣨⣭⣿⣿⣿⣿⣿⣿⣿⡟⠛⣿⣿⣿⣿21/// ⣿⣿⣿⣿⣿⣿⡿⣿⣿⣿⣿⣿⣿⣆⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿22/// ⣿⣿⣿⡿⠿⠟⠉⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿23/// ⣿⣿⣿⣿⣆⠀⢀⣨⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠈⠻⣿⣿⣿⣿⡋⠀⢿⣿⣿⣿24/// ⣿⣿⣿⣿⣿⣶⣿⣿⣿⣿⣿⣿⣿⣿⣤⣄⡀⠀⠀⢀⣤⣼⣿⣿⣷⣿⣿⣿⣿⣿25/// ⣿⣿⣿⡟⢻⣿⣿⣿⣿⣿⣿⠿⠿⣿⣿⣿⣿⣆⢠⣿⣿⣿⣿⣿⢿⣿⣿⣿⣿⣿26/// ⣿⣿⣿⣷⣾⣿⣿⣿⣿⣿⣿⣄⣰⣿⣿⣿⣿⣿⣾⣿⣿⣿⣿⠏⣿⣿⣿⣿⣿⣿27/// ⣿⣿⣿⣿⣿⣿⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠟⠛⠁⠀⢹⣿⣿⣿⣿⣿28/// ⣿⣿⣿⣿⣿⡿⠀⠀⠈⠉⢉⣿⣿⣿⡿⣿⣿⣿⣷⣦⡀⠀⠀⠀⠀⠙⠿⣿⣿⣿29/// ⣿⣿⣿⣿⡟⠁⠀⠀⠀⢠⣿⣿⣿⠀⠀⢿⣿⣿⣿⣿⣿⡆⠀⣠⣴⣶⣿⣷⣿⣿30/// ⣿⣿⣿⣿⣿⣿⣿⣿⣦⣼⣿⣿⣿⣾⣿⣷⣿⣿⣿⣿⣿⣇⣾⣿⣿⡏⢹⣿⣿⣿31/// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡋⢛⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿32/// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿33
34#define jumptable__packed TABLE = {35 name generate verify36}37
38// - start here39// |40// v41#define macro MAIN() = takes (0) returns (0) {42 __tablestart(TABLE)43 push0 calldataload 0xfc shr44 dup1 0x04 lt45 fail jumpi46 add47 0x02 swap148 0x1E49 codecopy50 push0 mload jump51
52 name:53 NAME()54 generate:55 0x04 calldataload56 GENERATE()57 verify:58 ANTIKYTHERA(ret_false)59 fail:60 push0 push0 revert61 ret_false:62 push0 push0 mstore63 0x20 push0 return64}65
66/// wWWWw wWWWw67/// vVVVv (___) wWWWw (___) vVVVv68/// (___) ~Y~ (___) vVVVv ~Y~ (___)69/// ~Y~ \| ~Y~ (___) |/ ~Y~70/// \| \ |/ \| / \~Y~/ \| \ |/71/// \\|// \\|// \\|/// \\|// \\|// \\\|///72/// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^73
74/// @notice Returns the name of the puzzle75#define macro NAME() = takes (0) returns (0) {76 0x0B416E74696B797468657261 // ["Antikythera"]77 0x2B mstore // []78 0x20 push0 mstore // []79 msize push0 return //<-80}81
82/// _____83/// |A . | _____84/// | /.\ ||A ^ | _____85/// |(_._)|| / \ ||A _ | _____86/// | | || \ / || ( ) ||A_ _ |87/// |____V|| . ||(_'_)||( v )|88/// |____V|| | || \ / |89/// |____V|| . |90/// |____V|91
92/// @notice Generates the puzzle's starting position based on a seed.93/// @dev The seed is intended to be `msg.sender` of some wrapper function or94/// call.95/// @param _seed The seed to use to generate the puzzle.96/// @return The puzzle's starting position.97#define macro GENERATE() = takes (1) returns (0) {98 // Input: [_seed]99
100 push0 mstore // []101 gas 0x20 mstore // []102 msize push0 sha3 // [_start]103 push0 mstore // []104 0x20 push0 return //<-105}106
107/// `-:-. ,-;"`-:-. ,-;"`-:-. ,-;"`-:-. ,-;"108/// `=`,'=/ `=`,'=/ `=`,'=/ `=`,'=/109/// y==/ y==/ y==/ y==/110/// ,=,-<=`. ,=,-<=`. ,=,-<=`. ,=,-<=`.111/// ,-'-' `-=_,-'-' `-=_,-'-' `-=_,-'-' `-=_112
113#define macro ANTIKYTHERA(ret_false) = takes (0) returns (0) {114 0x04 calldataload115 0x24 calldataload116 117 // ----------------------------118 // PHASE 1: Dirty Bits119 // ----------------------------120
121 dup1 0x10 byte122 dup1123 dup4 0x12 byte124 and125 iszero <ret_false> jumpi126
127 0x0F and128 pc 0x04 shr eq129 iszero <ret_false> jumpi130 131 // ----------------------------132 // PHASE 2: Crank133 // ----------------------------134
135 dup1 0x80 shr 0x80 shl136 CRANK(<ret_false>)137
138 // ----------------------------139 // PHASE 3: Truffle Shuffle140 // ----------------------------141
142 dup2 push0 mstore143 dup1 0x1E byte144 0x05 push0 dup5145 MECHS__ONE_WAY_SHUFFLE(push0, 0x20)146 pop147
148 push0 mload149 0x0F and 0x0F eq150 iszero <ret_false> jumpi151 152 // ----------------------------153 // PHASE 4: Budget Cuts154 // ----------------------------155
156 dup1 0x10 byte157 0x04 shr158 dup1 0x02 gt159 <ret_false> jumpi160 gas mod161 <ret_false> jumpi162
163 // ----------------------------164 // PHASE 5: >_ sudo su165 // ----------------------------166
167 dup1 0x0a byte168 0x05 shl169 0x14 add170 mload171 0xFF eq172 iszero <ret_false> jumpi173
174 // ----------------------------175 // PHASE 6: 31303532176 // ----------------------------177
178 dup1 0xFFFF 0x58 shl and179 0x58 shr180 extcodehash181 dup2 0x17 byte182 shl183 0xFFFFF and184 0x80000 eq185 iszero <ret_false> jumpi186
187 // ----------------------------188 // Finish Line189 // ----------------------------190
191 dup1 0x1F byte192 push0 mstore193 0x20 push0 return194}195
196/// __197/// / _\ #198/// \c / #199/// / \___ #200/// \`----`#==> 201/// | \ #202/// ,%.-"""---'`--'\#_203/// %%/ |__`\204/// .%'\ | \ / //205/// ,%' > .'----\ | [/206/// < <<` ||207/// `\\\ ||208/// )\\ )\209/// ^^^^^^^^"""^^^^^^""^^^^^^^^^^210
211#define jumptable__packed GEARS {212 pinion lead sun lever ring213}214
215#define macro CRANK(ret_false) = takes (3) returns (0) {216 push0217 turn:218 __tablestart(GEARS)219 dup3 push0 byte220 dup1 0xFF eq snaggletooth jumpi221 dup1 0x04 lt <ret_false> jumpi222
223 chainid shl224 add225 0x02 swap1226 0x1E227 codecopy228 swap1229 push0 mload jump230 EPICYCLICAL_GEARING()231 turn jump232 snaggletooth:233 pop pop234 dup4 0xFFFFFF and eq iszero235 <ret_false> jumpi236 pop237}238
239/// @dev Don't fix what ain't broke.240#define macro EPICYCLICAL_GEARING() = takes (1) returns (2) {241 pinion:242 dup1 0x03 byte dup2 0x02 byte243 dup3 chainid byte mul div244 245 swap1246 0x20 shl247 swap1248
249 planet jump250 lead:251 // \_______/252 // `.,-'\_____/`-.,'253 // /`..'\ _ /`.,'\254 // / /`.,' `.,'\ \255 // /__/__/ \__\__\__ / _ \256 // \ \ \ / / / \_\(_)/_/257 // \ \,'`._,'`./ / _//o\\_258 // \,'`./___\,'`./ / \259 // ,'`-./_____\,-'`.260 // / \261 //262
263 dup1 chainid byte dup2 0x02 byte and264
265 swap1 0x18 shl266 swap1267
268 planet jump269 sun:270 dup1 chainid byte271 dup2 0x02 byte shr272
273 swap1 0x18 shl274 swap1275
276 planet jump277 lever:278 dup1 chainid byte dup2 0x02 byte279 shl280
281 swap1 0x18 shl282 swap1283
284 planet jump285 ring:286 dup1 chainid byte dup1 dup3 0x02 byte287 swap1288 chainid swap1 sub add289
290 swap1 0x05 shl 0x14 add291 0xFF swap1 mstore292
293 swap1294 0x18 shl swap1295 planet:296 swap1 swap2 add297}298
Time Left
Solve locally (WIP)
- Clone GitHub repo + install deps
git clone https://github.com/waterfall-mkt/curta-puzzles.git && cd curta-puzzles && forge install
- Set
RPC_URL_MAINNET
in.env
.env
RPC_URL_MAINNET=""
- Write solution + run script
forge script <PATH_TO_PUZZLE> -f mainnet -vvv
This is still WIP.