creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/Copia.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.16;\n\nimport \"solady/src/utils/SSTORE2.sol\";\n\ncontract Copia {\n    /**\n     * @notice writes data via sstore2\n     */\n    function write(bytes[] calldata d) public {\n        for (uint8 i = 0; i < d.length; i++) {\n            SSTORE2.write(d[i]);\n        }\n    }\n    \n    /**\n     * @notice reads data from \"a\" via SSTORE2\n     * \n     * @param a the address to read from\n     */\n    function read(address a) public view returns(bytes memory d) {\n        return SSTORE2.read(a);\n    }\n}"
      },
      "solady/src/utils/SSTORE2.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Read and write to persistent storage at a fraction of the cost.\n/// @author Solady (https://github.com/vectorized/solmady/blob/main/src/utils/SSTORE2.sol)\n/// @author Saw-mon-and-Natalie (https://github.com/Saw-mon-and-Natalie)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SSTORE2.sol)\n/// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol)\nlibrary SSTORE2 {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev We skip the first byte as it's a STOP opcode,\n    /// which ensures the contract can't be called.\n    uint256 internal constant DATA_OFFSET = 1;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                        CUSTOM ERRORS                       */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Unable to deploy the storage contract.\n    error DeploymentFailed();\n\n    /// @dev The storage contract address is invalid.\n    error InvalidPointer();\n\n    /// @dev Attempt to read outside of the storage contract's bytecode bounds.\n    error ReadOutOfBounds();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         WRITE LOGIC                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Writes `data` into the bytecode of a storage contract and returns its address.\n    function write(bytes memory data) internal returns (address pointer) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let originalDataLength := mload(data)\n\n            // Add 1 to data size since we are prefixing it with a STOP opcode.\n            let dataSize := add(originalDataLength, DATA_OFFSET)\n\n            /**\n             * ------------------------------------------------------------------------------+\n             * Opcode      | Mnemonic        | Stack                   | Memory              |\n             * ------------------------------------------------------------------------------|\n             * 61 dataSize | PUSH2 dataSize  | dataSize                |                     |\n             * 80          | DUP1            | dataSize dataSize       |                     |\n             * 60 0xa      | PUSH1 0xa       | 0xa dataSize dataSize   |                     |\n             * 3D          | RETURNDATASIZE  | 0 0xa dataSize dataSize |                     |\n             * 39          | CODECOPY        | dataSize                | [0..dataSize): code |\n             * 3D          | RETURNDATASIZE  | 0 dataSize              | [0..dataSize): code |\n             * F3          | RETURN          |                         | [0..dataSize): code |\n             * 00          | STOP            |                         |                     |\n             * ------------------------------------------------------------------------------+\n             * @dev Prefix the bytecode with a STOP opcode to ensure it cannot be called.\n             * Also PUSH2 is used since max contract size cap is 24,576 bytes which is less than 2 ** 16.\n             */\n            mstore(\n                // Do a out-of-gas revert if `dataSize` is more than 2 bytes.\n                // The actual EVM limit may be smaller and may change over time.\n                add(data, gt(dataSize, 0xffff)),\n                // Left shift `dataSize` by 64 so that it lines up with the 0000 after PUSH2.\n                or(0xfd61000080600a3d393df300, shl(0x40, dataSize))\n            )\n\n            // Deploy a new contract with the generated creation code.\n            pointer := create(0, add(data, 0x15), add(dataSize, 0xa))\n\n            // If `pointer` is zero, revert.\n            if iszero(pointer) {\n                // Store the function selector of `DeploymentFailed()`.\n                mstore(0x00, 0x30116425)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n\n            // Restore original length of the variable size `data`.\n            mstore(data, originalDataLength)\n        }\n    }\n\n    /// @dev Writes `data` into the bytecode of a storage contract with `salt`\n    /// and returns its deterministic address.\n    function writeDeterministic(bytes memory data, bytes32 salt)\n        internal\n        returns (address pointer)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let originalDataLength := mload(data)\n            let dataSize := add(originalDataLength, DATA_OFFSET)\n\n            mstore(\n                // Do a out-of-gas revert if `dataSize` is more than 2 bytes.\n                // The actual EVM limit may be smaller and may change over time.\n                add(data, gt(dataSize, 0xffff)),\n                // Left shift `dataSize` by 64 so that it lines up with the 0000 after PUSH2.\n                or(0xfd61000080600a3d393df300, shl(0x40, dataSize))\n            )\n\n            // Deploy a new contract with the generated creation code.\n            pointer := create2(0, add(data, 0x15), add(dataSize, 0xa), salt)\n\n            // If `pointer` is zero, revert.\n            if iszero(pointer) {\n                // Store the function selector of `DeploymentFailed()`.\n                mstore(0x00, 0x30116425)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n\n            // Restore original length of the variable size `data`.\n            mstore(data, originalDataLength)\n        }\n    }\n\n    /// @dev Returns the initialization code hash of the storage contract for `data`.\n    /// Used for mining vanity addresses with create2crunch.\n    function initCodeHash(bytes memory data) internal pure returns (bytes32 hash) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let originalDataLength := mload(data)\n            let dataSize := add(originalDataLength, DATA_OFFSET)\n\n            // Do a out-of-gas revert if `dataSize` is more than 2 bytes.\n            // The actual EVM limit may be smaller and may change over time.\n            returndatacopy(returndatasize(), returndatasize(), shr(16, dataSize))\n\n            mstore(data, or(0x61000080600a3d393df300, shl(0x40, dataSize)))\n\n            hash := keccak256(add(data, 0x15), add(dataSize, 0xa))\n\n            // Restore original length of the variable size `data`.\n            mstore(data, originalDataLength)\n        }\n    }\n\n    /// @dev Returns the address of the storage contract for `data`\n    /// deployed with `salt` by `deployer`.\n    /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly.\n    function predictDeterministicAddress(bytes memory data, bytes32 salt, address deployer)\n        internal\n        pure\n        returns (address predicted)\n    {\n        bytes32 hash = initCodeHash(data);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute and store the bytecode hash.\n            mstore8(0x00, 0xff) // Write the prefix.\n            mstore(0x35, hash)\n            mstore(0x01, shl(96, deployer))\n            mstore(0x15, salt)\n            predicted := keccak256(0x00, 0x55)\n            // Restore the part of the free memory pointer that has been overwritten.\n            mstore(0x35, 0)\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         READ LOGIC                         */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns all the `data` from the bytecode of the storage contract at `pointer`.\n    function read(address pointer) internal view returns (bytes memory data) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let pointerCodesize := extcodesize(pointer)\n            if iszero(pointerCodesize) {\n                // Store the function selector of `InvalidPointer()`.\n                mstore(0x00, 0x11052bb4)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n            // Offset all indices by 1 to skip the STOP opcode.\n            let size := sub(pointerCodesize, DATA_OFFSET)\n\n            // Get the pointer to the free memory and allocate\n            // enough 32-byte words for the data and the length of the data,\n            // then copy the code to the allocated memory.\n            // Masking with 0xffe0 will suffice, since contract size is less than 16 bits.\n            data := mload(0x40)\n            mstore(0x40, add(data, and(add(size, 0x3f), 0xffe0)))\n            mstore(data, size)\n            mstore(add(add(data, 0x20), size), 0) // Zeroize the last slot.\n            extcodecopy(pointer, add(data, 0x20), DATA_OFFSET, size)\n        }\n    }\n\n    /// @dev Returns the `data` from the bytecode of the storage contract at `pointer`,\n    /// from the byte at `start`, to the end of the data stored.\n    function read(address pointer, uint256 start) internal view returns (bytes memory data) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let pointerCodesize := extcodesize(pointer)\n            if iszero(pointerCodesize) {\n                // Store the function selector of `InvalidPointer()`.\n                mstore(0x00, 0x11052bb4)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n\n            // If `!(pointer.code.size > start)`, reverts.\n            // This also handles the case where `start + DATA_OFFSET` overflows.\n            if iszero(gt(pointerCodesize, start)) {\n                // Store the function selector of `ReadOutOfBounds()`.\n                mstore(0x00, 0x84eb0dd1)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n            let size := sub(pointerCodesize, add(start, DATA_OFFSET))\n\n            // Get the pointer to the free memory and allocate\n            // enough 32-byte words for the data and the length of the data,\n            // then copy the code to the allocated memory.\n            // Masking with 0xffe0 will suffice, since contract size is less than 16 bits.\n            data := mload(0x40)\n            mstore(0x40, add(data, and(add(size, 0x3f), 0xffe0)))\n            mstore(data, size)\n            mstore(add(add(data, 0x20), size), 0) // Zeroize the last slot.\n            extcodecopy(pointer, add(data, 0x20), add(start, DATA_OFFSET), size)\n        }\n    }\n\n    /// @dev Returns the `data` from the bytecode of the storage contract at `pointer`,\n    /// from the byte at `start`, to the byte at `end` (exclusive) of the data stored.\n    function read(address pointer, uint256 start, uint256 end)\n        internal\n        view\n        returns (bytes memory data)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let pointerCodesize := extcodesize(pointer)\n            if iszero(pointerCodesize) {\n                // Store the function selector of `InvalidPointer()`.\n                mstore(0x00, 0x11052bb4)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n\n            // If `!(pointer.code.size > end) || (start > end)`, revert.\n            // This also handles the cases where\n            // `end + DATA_OFFSET` or `start + DATA_OFFSET` overflows.\n            if iszero(\n                and(\n                    gt(pointerCodesize, end), // Within bounds.\n                    iszero(gt(start, end)) // Valid range.\n                )\n            ) {\n                // Store the function selector of `ReadOutOfBounds()`.\n                mstore(0x00, 0x84eb0dd1)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n            let size := sub(end, start)\n\n            // Get the pointer to the free memory and allocate\n            // enough 32-byte words for the data and the length of the data,\n            // then copy the code to the allocated memory.\n            // Masking with 0xffe0 will suffice, since contract size is less than 16 bits.\n            data := mload(0x40)\n            mstore(0x40, add(data, and(add(size, 0x3f), 0xffe0)))\n            mstore(data, size)\n            mstore(add(add(data, 0x20), size), 0) // Zeroize the last slot.\n            extcodecopy(pointer, add(data, 0x20), add(start, DATA_OFFSET), size)\n        }\n    }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 1000
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}