Puzzle #18
β π‘π β
Author
1// SPDX-License-Identifier: MIT2pragma solidity 0.8.21;3
4import { IPuzzle } from "curta/src/interfaces/IPuzzle.sol";5import { LibClone } from "solady/src/utils/LibClone.sol";6
7/**8 *                              βββ   β π‘π β   βββ9 *                           ββ         β          ββ10 *                       ββ             π‘              ββ11 *                    ββ              β   β               ββ12 *                  ββ               π‘      π‘               ββ13 *                ββ                β        β               ββ14 *               ββ               β           β               ββ15 *              ββ               β              β              ββ16 *             ββ              β β β β β β β β β β             ββ17 *             ββ            β β     π‘π‘βπβπ‘π‘     β β            ββ18 *             ββ          β   β   π‘β        βπ‘  β  β           ββ19 *             ββ         β    β π‘β           βπ‘ β    β         ββ20 *             ββ       π‘      β π‘β           βπ‘ β      π‘       ββ21 *              ββ    β        β   π‘β       βπ‘   β        β    ββ22 *               ββ β          β     π‘π‘βπβπ‘π‘     β          β ββ23 *                βπ‘ β β β β β β β β β β β β β β β β β β β β π‘β24 *                  ββ                                      ββ25 *                    ββ                                  ββ26 *                       ββ                            ββ27 *                           ββ                    ββ28 *                              βββ   β π‘π β   βββ29 *30 * @title β π‘π β31 *32 * @notice "The World hath been much abused by the Opinion of Making of Gold:33 *          The Worke it selfe I judge to be possible; But the Meanes to effect34 *          it, are, in the Practice, full of Errour and Imposture; And in the35 *          Theory, full of unsound Imaginations."36 *37 *         - Francis Bacon, 162738 *39 * @author horsefacts.eth <[email protected]>40 */41contract PhilosophersStone is IPuzzle {42  using LibClone for address;43
44  struct Trial {45    uint32 aeon;46    address arcanum;47    uint8 phase;48  }49
50  address codex;51  mapping(uint256 => Trial) trials;52  mapping(address => bool) elixirs;53
54  constructor() {55    codex = address(new Codex());56    codex.call(57      abi.encodeWithSignature(58        "prepare(address,address,bytes4)", address(0), address(0), bytes4(0)59      )60    );61  }62
63  function name() external pure returns (string memory) {64    return unicode"β π‘π β";65  }66
67  function generate(address _seed) public pure returns (uint256) {68    return uint256(keccak256(abi.encode(_seed)));69  }70
71  function verify(uint256 _start, uint256 _solution) external view returns (bool) {72    Trial memory trial = trials[_start];73    require(trial.arcanum == address(uint160(_solution)));74    return trial.phase == 2;75  }76
77  function alter(address adept) public {78    require(elixirs[msg.sender]);79    elixirs[msg.sender] = false;80    uint256 sigil = generate(adept);81    trials[sigil].phase += 1;82  }83
84  function transmute(uint256 materia) external {85    uint256 sigil = generate(msg.sender);86    trials[sigil] = Trial({87      aeon: uint32(block.number),88      arcanum: address(uint160(materia)),89      phase: 090    });91  }92
93  function solve() external {94    uint256 sigil = generate(msg.sender);95    Trial memory trial = trials[sigil];96
97    require(trial.aeon == uint32(block.number));98    require(trial.phase == 0);99
100    address materia = trial.arcanum;101    require(bytes3(materia.codehash) == 0x001ead);102
103    bytes32 salt = bytes32(abi.encodePacked(uint128(trial.aeon), uint128(sigil)));104    bytes4 essence = bytes4(bytes32(sigil));105
106    address elixir = codex.cloneDeterministic(salt);107    elixir.call(108      abi.encodeWithSignature(109        "prepare(address,address,bytes4)", msg.sender, materia, essence110      )111    );112    elixirs[elixir] = true;113  }114
115  function coagula() external {116    uint256 sigil = generate(msg.sender);117    Trial memory trial = trials[sigil];118
119    require(trial.aeon == uint32(block.number));120    require(trial.phase == 1);121
122    address materia = trial.arcanum;123    require(bytes3(materia.codehash) == 0x00901d);124
125    bytes32 salt = bytes32(abi.encodePacked(uint128(trial.aeon), uint128(sigil >> 128)));126    bytes4 essence = bytes4(bytes32(sigil) << 32);127
128    address elixir = codex.cloneDeterministic(salt);129    elixir.call(130      abi.encodeWithSignature(131        "prepare(address,address,bytes4)", msg.sender, materia, essence132      )133    );134    elixirs[elixir] = true;135  }136}137
138contract Codex {139  address stone;140  uint256 aeon;141  address adept;142  address materia;143  bytes4 essence;144
145  constructor() {146    bytes memory elixir = (147      hex"608060405234801561001057600080fd5b50600436106100575760003560e01c806383"148      hex"197ef01461005c578063841271ed146100665780638bbbb2e21461006e578063a69dc2"149      hex"7414610081578063cd57c8ea14610089575b600080fd5b610064610091565b005b6100"150      hex"64610128565b61006461007c36600461046f565b610264565b6100646102d3565b6100"151      hex"6461035c565b6002546001600160a01b031633146100a857600080fd5b436001541461"152      hex"00b657600080fd5b6003546040516655895656d5895560c91b81526000918291600160"153      hex"0160a01b03909116906007016000604051808303816000865af19150503d8060008114"154      hex"61011a576040519150601f19603f3d011682016040523d82523d6000602084013e6101"155      hex"1f565b606091505b50909250905033ff5b6002546001600160a01b0316331461013f57"156      hex"600080fd5b436001541461014d57600080fd5b6003546040516655895656d5895560c9"157      hex"1b815260009182916001600160a01b0390911690600701600060405180830381600086"158      hex"5af19150503d80600081146101b1576040519150601f19603f3d011682016040523d82"159      hex"523d6000602084013e6101b6565b606091505b5091509150816101c557600080fd5b60"160      hex"00818060200190518101906101db91906104b6565b6003549091506001600160e01b03"161      hex"19808316600160a01b90920460e01b161461020357600080fd5b60005460405163b10a"162      hex"582160e01b81523360048201526001600160a01b039091169063b10a58219060240160"163      hex"0060405180830381600087803b15801561024857600080fd5b505af115801561025c57"164      hex"3d6000803e3d6000fd5b503392505050ff5b6000546001600160a01b03161561027a57"165      hex"600080fd5b600080546001600160a01b03199081163317909155436001556002805460"166      hex"01600160a01b0395861692169190911790556003805460e09290921c600160a01b0260"167      hex"01600160c01b03199092169290931691909117179055565b6002546001600160a01b03"168      hex"1633146102ea57600080fd5b43600154146102f857600080fd5b600354604051665589"169      hex"5656d5895560c91b815260009182916001600160a01b03909116906007016000604051"170      hex"808303816000865af19150503d8060008114610057576040519150601f19603f3d0116"171      hex"82016040523d82523d6000602084013e600080fd5b6002546001600160a01b03163314"172      hex"61037357600080fd5b436001541461038157600080fd5b6003546040516655895656d5"173      hex"895560c91b815260009182916001600160a01b03909116906007016000604051808303"174      hex"816000865af19150503d80600081146103e5576040519150601f19603f3d0116820160"175      hex"40523d82523d6000602084013e6103ea565b606091505b5091509150816103f9576000"176      hex"80fd5b60008180602001905181019061040f91906104b6565b60035490915060016001"177      hex"60e01b0319808316600160a01b90920460e01b161461043757600080fd5b33ff5b8035"178      hex"6001600160a01b038116811461045157600080fd5b919050565b6001600160e01b0319"179      hex"8116811461046c57600080fd5b50565b60008060006060848603121561048457600080"180      hex"fd5b61048d8461043a565b925061049b6020850161043a565b915060408401356104ab"181      hex"81610456565b809150509250925092565b6000602082840312156104c857600080fd5b"182      hex"81516104d381610456565b939250505056fea164736f6c6343000815000a"183    );184    assembly {185      return(add(elixir, 0x20), mload(elixir))186    }187  }188}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_MAINNETin.env
.env
RPC_URL_MAINNET=""- Write solution + run script
forge script <PATH_TO_PUZZLE> -f mainnet -vvvThis is still WIP.