Puzzle #9
Antikythera
Author
0xa41fd464c84b5afcfa9fe58545564d49ec04c1d3
clabby.eth
HuffHuff's logo.Puzzle
Curtacallsverify()
1
/// @title Antikythera
2
/// @author @vex_0x
3
/// @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 puzzle
12
#define function name() view returns (string memory)
13
/// @notice Verifies that a solution is valid for the puzzle
14
#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 verify
36
}
37
38
// - start here
39
// |
40
// v
41
#define macro MAIN() = takes (0) returns (0) {
42
__tablestart(TABLE)
43
push0 calldataload 0xfc shr
44
dup1 0x04 lt
45
fail jumpi
46
add
47
0x02 swap1
48
0x1E
49
codecopy
50
push0 mload jump
51
52
name:
53
NAME()
54
generate:
55
0x04 calldataload
56
GENERATE()
57
verify:
58
ANTIKYTHERA(ret_false)
59
fail:
60
push0 push0 revert
61
ret_false:
62
push0 push0 mstore
63
0x20 push0 return
64
}
65
66
/// wWWWw wWWWw
67
/// vVVVv (___) wWWWw (___) vVVVv
68
/// (___) ~Y~ (___) vVVVv ~Y~ (___)
69
/// ~Y~ \| ~Y~ (___) |/ ~Y~
70
/// \| \ |/ \| / \~Y~/ \| \ |/
71
/// \\|// \\|// \\|/// \\|// \\|// \\\|///
72
/// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
73
74
/// @notice Returns the name of the puzzle
75
#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 or
94
/// 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 calldataload
115
0x24 calldataload
116
117
// ----------------------------
118
// PHASE 1: Dirty Bits
119
// ----------------------------
120
121
dup1 0x10 byte
122
dup1
123
dup4 0x12 byte
124
and
125
iszero <ret_false> jumpi
126
127
0x0F and
128
pc 0x04 shr eq
129
iszero <ret_false> jumpi
130
131
// ----------------------------
132
// PHASE 2: Crank
133
// ----------------------------
134
135
dup1 0x80 shr 0x80 shl
136
CRANK(<ret_false>)
137
138
// ----------------------------
139
// PHASE 3: Truffle Shuffle
140
// ----------------------------
141
142
dup2 push0 mstore
143
dup1 0x1E byte
144
0x05 push0 dup5
145
MECHS__ONE_WAY_SHUFFLE(push0, 0x20)
146
pop
147
148
push0 mload
149
0x0F and 0x0F eq
150
iszero <ret_false> jumpi
151
152
// ----------------------------
153
// PHASE 4: Budget Cuts
154
// ----------------------------
155
156
dup1 0x10 byte
157
0x04 shr
158
dup1 0x02 gt
159
<ret_false> jumpi
160
gas mod
161
<ret_false> jumpi
162
163
// ----------------------------
164
// PHASE 5: >_ sudo su
165
// ----------------------------
166
167
dup1 0x0a byte
168
0x05 shl
169
0x14 add
170
mload
171
0xFF eq
172
iszero <ret_false> jumpi
173
174
// ----------------------------
175
// PHASE 6: 31303532
176
// ----------------------------
177
178
dup1 0xFFFF 0x58 shl and
179
0x58 shr
180
extcodehash
181
dup2 0x17 byte
182
shl
183
0xFFFFF and
184
0x80000 eq
185
iszero <ret_false> jumpi
186
187
// ----------------------------
188
// Finish Line
189
// ----------------------------
190
191
dup1 0x1F byte
192
push0 mstore
193
0x20 push0 return
194
}
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 ring
213
}
214
215
#define macro CRANK(ret_false) = takes (3) returns (0) {
216
push0
217
turn:
218
__tablestart(GEARS)
219
dup3 push0 byte
220
dup1 0xFF eq snaggletooth jumpi
221
dup1 0x04 lt <ret_false> jumpi
222
223
chainid shl
224
add
225
0x02 swap1
226
0x1E
227
codecopy
228
swap1
229
push0 mload jump
230
EPICYCLICAL_GEARING()
231
turn jump
232
snaggletooth:
233
pop pop
234
dup4 0xFFFFFF and eq iszero
235
<ret_false> jumpi
236
pop
237
}
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 byte
243
dup3 chainid byte mul div
244
245
swap1
246
0x20 shl
247
swap1
248
249
planet jump
250
lead:
251
// \_______/
252
// `.,-'\_____/`-.,'
253
// /`..'\ _ /`.,'\
254
// / /`.,' `.,'\ \
255
// /__/__/ \__\__\__ / _ \
256
// \ \ \ / / / \_\(_)/_/
257
// \ \,'`._,'`./ / _//o\\_
258
// \,'`./___\,'`./ / \
259
// ,'`-./_____\,-'`.
260
// / \
261
//
262
263
dup1 chainid byte dup2 0x02 byte and
264
265
swap1 0x18 shl
266
swap1
267
268
planet jump
269
sun:
270
dup1 chainid byte
271
dup2 0x02 byte shr
272
273
swap1 0x18 shl
274
swap1
275
276
planet jump
277
lever:
278
dup1 chainid byte dup2 0x02 byte
279
shl
280
281
swap1 0x18 shl
282
swap1
283
284
planet jump
285
ring:
286
dup1 chainid byte dup1 dup3 0x02 byte
287
swap1
288
chainid swap1 sub add
289
290
swap1 0x05 shl 0x14 add
291
0xFF swap1 mstore
292
293
swap1
294
0x18 shl swap1
295
planet:
296
swap1 swap2 add
297
}
298
First Blood
chainlight.io
02:17:00
17
Time Left

Solve locally (WIP)

  1. Clone GitHub repo + install deps
git clone https://github.com/waterfall-mkt/curta-puzzles.git && cd curta-puzzles && forge install
  1. Set RPC_URL_MAINNET in .env
.env
RPC_URL_MAINNET=""
  1. Write solution + run script
forge script <PATH_TO_PUZZLE> -f mainnet -vvv
This is still WIP.
Waterfall