Commit 83823b0e authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge pull request #4795 from ethereum-optimism/sc/ctp-atst-1.1.0

feat(ctp): ATST 1.1.0 artifacts
parents 5e8bc3d5 24cacaea
{ {
"address": "0x1BEb19F1685ddF2F774884902119Fa2FA5d8f509", "address": "0xbeD744818e96AAD8a51324291a6f6Cb20A0c22be",
"abi": [ "abi": [
{ {
"inputs": [], "inputs": [],
...@@ -67,6 +67,29 @@ ...@@ -67,6 +67,29 @@
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "address",
"name": "_about",
"type": "address"
},
{
"internalType": "bytes32",
"name": "_key",
"type": "bytes32"
},
{
"internalType": "bytes",
"name": "_val",
"type": "bytes"
}
],
"name": "attest",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
...@@ -110,28 +133,28 @@ ...@@ -110,28 +133,28 @@
"type": "function" "type": "function"
} }
], ],
"transactionHash": "0xfea89fc1eefeaa83bd8d88eb9002594746c12b6761d674f82e821567483df315", "transactionHash": "0x4c0aae61c0030872cb5f8654c36fbc192cfab6f09f93df5c0f80268382d964e9",
"receipt": { "receipt": {
"to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", "from": "0x956a5152D0f498dBA0c5966577bb44262F8F7078",
"contractAddress": null, "contractAddress": null,
"transactionIndex": 0, "transactionIndex": 1,
"gasUsed": "645110", "gasUsed": "666309",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x6043e32ed00ca470e6676a00f619eb1fed995b06b0159f77ff545b950bae515a", "blockHash": "0xe683044625d767223da2ecd65fd81a34251ffbef27abd3302530be36e99971d0",
"transactionHash": "0xfea89fc1eefeaa83bd8d88eb9002594746c12b6761d674f82e821567483df315", "transactionHash": "0x4c0aae61c0030872cb5f8654c36fbc192cfab6f09f93df5c0f80268382d964e9",
"logs": [], "logs": [],
"blockNumber": 3451191, "blockNumber": 4667191,
"cumulativeGasUsed": "645110", "cumulativeGasUsed": "666309",
"status": 1, "status": 1,
"byzantium": true "byzantium": true
}, },
"args": [], "args": [],
"numDeployments": 1, "numDeployments": 2,
"solcInputHash": "45837d34ff24b9cb2ae34232b60ea874", "solcInputHash": "3aa2ad7d005d9515a1f12df8da17d178",
"metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"about\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"val\",\"type\":\"bytes\"}],\"name\":\"AttestationCreated\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"about\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"val\",\"type\":\"bytes\"}],\"internalType\":\"struct AttestationStation.AttestationData[]\",\"name\":\"_attestations\",\"type\":\"tuple[]\"}],\"name\":\"attest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"attestations\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Optimism CollectiveGitcoin\",\"events\":{\"AttestationCreated(address,address,bytes32,bytes)\":{\"params\":{\"about\":\"Address attestation is about.\",\"creator\":\"Address that made the attestation.\",\"key\":\"Key of the attestation.\",\"val\":\"Value of the attestation.\"}}},\"kind\":\"dev\",\"methods\":{\"attest((address,bytes32,bytes)[])\":{\"params\":{\"_attestations\":\"An array of attestation data.\"}},\"constructor\":{\"custom:semver\":\"1.0.0\"},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"AttestationStation\",\"version\":1},\"userdoc\":{\"events\":{\"AttestationCreated(address,address,bytes32,bytes)\":{\"notice\":\"Emitted when Attestation is created.\"}},\"kind\":\"user\",\"methods\":{\"attest((address,bytes32,bytes)[])\":{\"notice\":\"Allows anyone to create attestations.\"},\"attestations(address,address,bytes32)\":{\"notice\":\"Maps addresses to attestations. Creator => About => Key => Value.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"Where attestations live.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/op-nft/AttestationStation.sol\":\"AttestationStation\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.15;\\n\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/**\\n * @title Semver\\n * @notice Semver is a simple contract for managing contract versions.\\n */\\ncontract Semver {\\n /**\\n * @notice Contract version number (major).\\n */\\n uint256 private immutable MAJOR_VERSION;\\n\\n /**\\n * @notice Contract version number (minor).\\n */\\n uint256 private immutable MINOR_VERSION;\\n\\n /**\\n * @notice Contract version number (patch).\\n */\\n uint256 private immutable PATCH_VERSION;\\n\\n /**\\n * @param _major Version number (major).\\n * @param _minor Version number (minor).\\n * @param _patch Version number (patch).\\n */\\n constructor(\\n uint256 _major,\\n uint256 _minor,\\n uint256 _patch\\n ) {\\n MAJOR_VERSION = _major;\\n MINOR_VERSION = _minor;\\n PATCH_VERSION = _patch;\\n }\\n\\n /**\\n * @notice Returns the full semver contract version.\\n *\\n * @return Semver contract version as a string.\\n */\\n function version() public view returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n Strings.toString(MAJOR_VERSION),\\n \\\".\\\",\\n Strings.toString(MINOR_VERSION),\\n \\\".\\\",\\n Strings.toString(PATCH_VERSION)\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x979b13465de4996a1105850abbf48abe7f71d5e18a8d4af318597ee14c165fdf\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/universal/op-nft/AttestationStation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\n\\n/**\\n * @title AttestationStation\\n * @author Optimism Collective\\n * @author Gitcoin\\n * @notice Where attestations live.\\n */\\ncontract AttestationStation is Semver {\\n /**\\n * @notice Struct representing data that is being attested.\\n *\\n * @custom:field about Address for which the attestation is about.\\n * @custom:field key A bytes32 key for the attestation.\\n * @custom:field val The attestation as arbitrary bytes.\\n */\\n struct AttestationData {\\n address about;\\n bytes32 key;\\n bytes val;\\n }\\n\\n /**\\n * @notice Maps addresses to attestations. Creator => About => Key => Value.\\n */\\n mapping(address => mapping(address => mapping(bytes32 => bytes))) public attestations;\\n\\n /**\\n * @notice Emitted when Attestation is created.\\n *\\n * @param creator Address that made the attestation.\\n * @param about Address attestation is about.\\n * @param key Key of the attestation.\\n * @param val Value of the attestation.\\n */\\n event AttestationCreated(\\n address indexed creator,\\n address indexed about,\\n bytes32 indexed key,\\n bytes val\\n );\\n\\n /**\\n * @custom:semver 1.0.0\\n */\\n constructor() Semver(1, 0, 0) {}\\n\\n /**\\n * @notice Allows anyone to create attestations.\\n *\\n * @param _attestations An array of attestation data.\\n */\\n function attest(AttestationData[] memory _attestations) public {\\n uint256 length = _attestations.length;\\n for (uint256 i = 0; i < length; ) {\\n AttestationData memory attestation = _attestations[i];\\n attestations[msg.sender][attestation.about][attestation.key] = attestation.val;\\n\\n emit AttestationCreated(\\n msg.sender,\\n attestation.about,\\n attestation.key,\\n attestation.val\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x670fde721c291828c3f6343a40bb315dbbcc5e4411125158892ffe54459d69b7\",\"license\":\"MIT\"}},\"version\":1}", "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"about\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"val\",\"type\":\"bytes\"}],\"name\":\"AttestationCreated\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"about\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"val\",\"type\":\"bytes\"}],\"internalType\":\"struct AttestationStation.AttestationData[]\",\"name\":\"_attestations\",\"type\":\"tuple[]\"}],\"name\":\"attest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_about\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_val\",\"type\":\"bytes\"}],\"name\":\"attest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"attestations\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Optimism CollectiveGitcoin\",\"events\":{\"AttestationCreated(address,address,bytes32,bytes)\":{\"params\":{\"about\":\"Address attestation is about.\",\"creator\":\"Address that made the attestation.\",\"key\":\"Key of the attestation.\",\"val\":\"Value of the attestation.\"}}},\"kind\":\"dev\",\"methods\":{\"attest((address,bytes32,bytes)[])\":{\"params\":{\"_attestations\":\"An array of attestation data.\"}},\"attest(address,bytes32,bytes)\":{\"params\":{\"_about\":\"Address that the attestation is about.\",\"_key\":\"A key used to namespace the attestation.\",\"_val\":\"An arbitrary value stored as part of the attestation.\"}},\"constructor\":{\"custom:semver\":\"1.1.0\"},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"AttestationStation\",\"version\":1},\"userdoc\":{\"events\":{\"AttestationCreated(address,address,bytes32,bytes)\":{\"notice\":\"Emitted when Attestation is created.\"}},\"kind\":\"user\",\"methods\":{\"attest((address,bytes32,bytes)[])\":{\"notice\":\"Allows anyone to create attestations.\"},\"attest(address,bytes32,bytes)\":{\"notice\":\"Allows anyone to create an attestation.\"},\"attestations(address,address,bytes32)\":{\"notice\":\"Maps addresses to attestations. Creator => About => Key => Value.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"Where attestations live.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/op-nft/AttestationStation.sol\":\"AttestationStation\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.15;\\n\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/**\\n * @title Semver\\n * @notice Semver is a simple contract for managing contract versions.\\n */\\ncontract Semver {\\n /**\\n * @notice Contract version number (major).\\n */\\n uint256 private immutable MAJOR_VERSION;\\n\\n /**\\n * @notice Contract version number (minor).\\n */\\n uint256 private immutable MINOR_VERSION;\\n\\n /**\\n * @notice Contract version number (patch).\\n */\\n uint256 private immutable PATCH_VERSION;\\n\\n /**\\n * @param _major Version number (major).\\n * @param _minor Version number (minor).\\n * @param _patch Version number (patch).\\n */\\n constructor(\\n uint256 _major,\\n uint256 _minor,\\n uint256 _patch\\n ) {\\n MAJOR_VERSION = _major;\\n MINOR_VERSION = _minor;\\n PATCH_VERSION = _patch;\\n }\\n\\n /**\\n * @notice Returns the full semver contract version.\\n *\\n * @return Semver contract version as a string.\\n */\\n function version() public view returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n Strings.toString(MAJOR_VERSION),\\n \\\".\\\",\\n Strings.toString(MINOR_VERSION),\\n \\\".\\\",\\n Strings.toString(PATCH_VERSION)\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x979b13465de4996a1105850abbf48abe7f71d5e18a8d4af318597ee14c165fdf\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/universal/op-nft/AttestationStation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\n\\n/**\\n * @title AttestationStation\\n * @author Optimism Collective\\n * @author Gitcoin\\n * @notice Where attestations live.\\n */\\ncontract AttestationStation is Semver {\\n /**\\n * @notice Struct representing data that is being attested.\\n *\\n * @custom:field about Address for which the attestation is about.\\n * @custom:field key A bytes32 key for the attestation.\\n * @custom:field val The attestation as arbitrary bytes.\\n */\\n struct AttestationData {\\n address about;\\n bytes32 key;\\n bytes val;\\n }\\n\\n /**\\n * @notice Maps addresses to attestations. Creator => About => Key => Value.\\n */\\n mapping(address => mapping(address => mapping(bytes32 => bytes))) public attestations;\\n\\n /**\\n * @notice Emitted when Attestation is created.\\n *\\n * @param creator Address that made the attestation.\\n * @param about Address attestation is about.\\n * @param key Key of the attestation.\\n * @param val Value of the attestation.\\n */\\n event AttestationCreated(\\n address indexed creator,\\n address indexed about,\\n bytes32 indexed key,\\n bytes val\\n );\\n\\n /**\\n * @custom:semver 1.1.0\\n */\\n constructor() Semver(1, 1, 0) {}\\n\\n /**\\n * @notice Allows anyone to create an attestation.\\n *\\n * @param _about Address that the attestation is about.\\n * @param _key A key used to namespace the attestation.\\n * @param _val An arbitrary value stored as part of the attestation.\\n */\\n function attest(\\n address _about,\\n bytes32 _key,\\n bytes memory _val\\n ) public {\\n attestations[msg.sender][_about][_key] = _val;\\n\\n emit AttestationCreated(msg.sender, _about, _key, _val);\\n }\\n\\n /**\\n * @notice Allows anyone to create attestations.\\n *\\n * @param _attestations An array of attestation data.\\n */\\n function attest(AttestationData[] calldata _attestations) external {\\n uint256 length = _attestations.length;\\n for (uint256 i = 0; i < length; ) {\\n AttestationData memory attestation = _attestations[i];\\n\\n attest(attestation.about, attestation.key, attestation.val);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x80718fdc09061ea8f8b99a0b846eee46c5a2a1372dbb0cbc3d40953cb3af19e0\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x60e060405234801561001057600080fd5b5060016080819052600060a081905260c081905280610aba61004a8239600061018f015260006101660152600061013d0152610aba6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806329b42cb51461004657806354fd4d501461006f5780635eb5ea1014610077575b600080fd5b610059610054366004610437565b61008c565b60405161006691906104ed565b60405180910390f35b610059610136565b61008a6100853660046105ae565b6101d9565b005b60006020818152938152604080822085529281528281209093528252902080546100b590610737565b80601f01602080910402602001604051908101604052809291908181526020018280546100e190610737565b801561012e5780601f106101035761010080835404028352916020019161012e565b820191906000526020600020905b81548152906001019060200180831161011157829003601f168201915b505050505081565b60606101617f00000000000000000000000000000000000000000000000000000000000000006102d1565b61018a7f00000000000000000000000000000000000000000000000000000000000000006102d1565b6101b37f00000000000000000000000000000000000000000000000000000000000000006102d1565b6040516020016101c59392919061078a565b604051602081830303815290604052905090565b805160005b818110156102cc5760008382815181106101fa576101fa610800565b602090810291909101810151604080820151336000908152808552828120845173ffffffffffffffffffffffffffffffffffffffff1682528552828120848601518252909452922090925090610250908261087d565b508060200151816000015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f28710dfecab43d1e29e02aa56b2e1e610c0bae19135c9cf7a83a1adb6df96d8584604001516040516102bb91906104ed565b60405180910390a4506001016101de565b505050565b60608160000361031457505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561033e5780610328816109c6565b91506103379050600a83610a2d565b9150610318565b60008167ffffffffffffffff81111561035957610359610507565b6040519080825280601f01601f191660200182016040528015610383576020820181803683370190505b5090505b841561040657610398600183610a41565b91506103a5600a86610a58565b6103b0906030610a6c565b60f81b8183815181106103c5576103c5610800565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506103ff600a86610a2d565b9450610387565b949350505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461043257600080fd5b919050565b60008060006060848603121561044c57600080fd5b6104558461040e565b92506104636020850161040e565b9150604084013590509250925092565b60005b8381101561048e578181015183820152602001610476565b8381111561049d576000848401525b50505050565b600081518084526104bb816020860160208601610473565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061050060208301846104a3565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561055957610559610507565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156105a6576105a6610507565b604052919050565b600060208083850312156105c157600080fd5b823567ffffffffffffffff808211156105d957600080fd5b818501915085601f8301126105ed57600080fd5b8135818111156105ff576105ff610507565b8060051b61060e85820161055f565b918252838101850191858101908984111561062857600080fd5b86860192505b8383101561072a578235858111156106465760008081fd5b860160607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828d03810182131561067d5760008081fd5b610685610536565b6106908b850161040e565b81526040848101358c8301529284013592898411156106af5760008081fd5b83850194508e603f8601126106c657600093508384fd5b8b8501359350898411156106dc576106dc610507565b6106ec8c84601f8701160161055f565b92508383528e818587010111156107035760008081fd5b838186018d85013760009383018c019390935291820152835250918601919086019061062e565b9998505050505050505050565b600181811c9082168061074b57607f821691505b602082108103610784577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000845161079c818460208901610473565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516107d8816001850160208a01610473565b600192019182015283516107f3816002840160208801610473565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b601f8211156102cc57600081815260208120601f850160051c810160208610156108565750805b601f850160051c820191505b8181101561087557828155600101610862565b505050505050565b815167ffffffffffffffff81111561089757610897610507565b6108ab816108a58454610737565b8461082f565b602080601f8311600181146108fe57600084156108c85750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610875565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561094b5788860151825594840194600190910190840161092c565b508582101561098757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109f7576109f7610997565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610a3c57610a3c6109fe565b500490565b600082821015610a5357610a53610997565b500390565b600082610a6757610a676109fe565b500690565b60008219821115610a7f57610a7f610997565b50019056fea26469706673582212204abcd56633387050a41a0ae027bbf9077ae2fb5080fa84124e2aa381adb3f98964736f6c634300080f0033", "bytecode": "0x60e060405234801561001057600080fd5b506001608081905260a052600060c05260805160a05160c051610b1c61004f60003960006101ad015260006101840152600061015b0152610b1c6000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806329b42cb51461005157806354fd4d501461007a5780635eb5ea1014610082578063702b9dee14610097575b600080fd5b61006461005f36600461046c565b6100aa565b604051610071919061051e565b60405180910390f35b610064610154565b610095610090366004610538565b6101f7565b005b6100956100a5366004610687565b61025a565b60006020818152938152604080822085529281528281209093528252902080546100d3906106de565b80601f01602080910402602001604051908101604052809291908181526020018280546100ff906106de565b801561014c5780601f106101215761010080835404028352916020019161014c565b820191906000526020600020905b81548152906001019060200180831161012f57829003601f168201915b505050505081565b606061017f7f0000000000000000000000000000000000000000000000000000000000000000610306565b6101a87f0000000000000000000000000000000000000000000000000000000000000000610306565b6101d17f0000000000000000000000000000000000000000000000000000000000000000610306565b6040516020016101e393929190610731565b604051602081830303815290604052905090565b8060005b81811015610254576000848483818110610217576102176107a7565b905060200281019061022991906107d6565b61023290610814565b905061024b81600001518260200151836040015161025a565b506001016101fb565b50505050565b3360009081526020818152604080832073ffffffffffffffffffffffffffffffffffffffff871684528252808320858452909152902061029a82826108df565b50818373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f28710dfecab43d1e29e02aa56b2e1e610c0bae19135c9cf7a83a1adb6df96d85846040516102f9919061051e565b60405180910390a4505050565b60608160000361034957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610373578061035d81610a28565b915061036c9050600a83610a8f565b915061034d565b60008167ffffffffffffffff81111561038e5761038e6105ad565b6040519080825280601f01601f1916602001820160405280156103b8576020820181803683370190505b5090505b841561043b576103cd600183610aa3565b91506103da600a86610aba565b6103e5906030610ace565b60f81b8183815181106103fa576103fa6107a7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610434600a86610a8f565b94506103bc565b949350505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461046757600080fd5b919050565b60008060006060848603121561048157600080fd5b61048a84610443565b925061049860208501610443565b9150604084013590509250925092565b60005b838110156104c35781810151838201526020016104ab565b838111156102545750506000910152565b600081518084526104ec8160208601602086016104a8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061053160208301846104d4565b9392505050565b6000806020838503121561054b57600080fd5b823567ffffffffffffffff8082111561056357600080fd5b818501915085601f83011261057757600080fd5b81358181111561058657600080fd5b8660208260051b850101111561059b57600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126105ed57600080fd5b813567ffffffffffffffff80821115610608576106086105ad565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561064e5761064e6105ad565b8160405283815286602085880101111561066757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561069c57600080fd5b6106a584610443565b925060208401359150604084013567ffffffffffffffff8111156106c857600080fd5b6106d4868287016105dc565b9150509250925092565b600181811c908216806106f257607f821691505b60208210810361072b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600084516107438184602089016104a8565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855161077f816001850160208a016104a8565b6001920191820152835161079a8160028401602088016104a8565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261080a57600080fd5b9190910192915050565b60006060823603121561082657600080fd5b6040516060810167ffffffffffffffff828210818311171561084a5761084a6105ad565b8160405261085785610443565b835260208501356020840152604085013591508082111561087757600080fd5b50610884368286016105dc565b60408301525092915050565b601f8211156108da57600081815260208120601f850160051c810160208610156108b75750805b601f850160051c820191505b818110156108d6578281556001016108c3565b5050505b505050565b815167ffffffffffffffff8111156108f9576108f96105ad565b61090d8161090784546106de565b84610890565b602080601f831160018114610960576000841561092a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556108d6565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156109ad5788860151825594840194600190910190840161098e565b50858210156109e957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610a5957610a596109f9565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610a9e57610a9e610a60565b500490565b600082821015610ab557610ab56109f9565b500390565b600082610ac957610ac9610a60565b500690565b60008219821115610ae157610ae16109f9565b50019056fea2646970667358221220bfd4abacc1c2510682b093eea8745255cdd9f45c5b16c168540522a65ddc1f3264736f6c634300080f0033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806329b42cb51461004657806354fd4d501461006f5780635eb5ea1014610077575b600080fd5b610059610054366004610437565b61008c565b60405161006691906104ed565b60405180910390f35b610059610136565b61008a6100853660046105ae565b6101d9565b005b60006020818152938152604080822085529281528281209093528252902080546100b590610737565b80601f01602080910402602001604051908101604052809291908181526020018280546100e190610737565b801561012e5780601f106101035761010080835404028352916020019161012e565b820191906000526020600020905b81548152906001019060200180831161011157829003601f168201915b505050505081565b60606101617f00000000000000000000000000000000000000000000000000000000000000006102d1565b61018a7f00000000000000000000000000000000000000000000000000000000000000006102d1565b6101b37f00000000000000000000000000000000000000000000000000000000000000006102d1565b6040516020016101c59392919061078a565b604051602081830303815290604052905090565b805160005b818110156102cc5760008382815181106101fa576101fa610800565b602090810291909101810151604080820151336000908152808552828120845173ffffffffffffffffffffffffffffffffffffffff1682528552828120848601518252909452922090925090610250908261087d565b508060200151816000015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f28710dfecab43d1e29e02aa56b2e1e610c0bae19135c9cf7a83a1adb6df96d8584604001516040516102bb91906104ed565b60405180910390a4506001016101de565b505050565b60608160000361031457505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561033e5780610328816109c6565b91506103379050600a83610a2d565b9150610318565b60008167ffffffffffffffff81111561035957610359610507565b6040519080825280601f01601f191660200182016040528015610383576020820181803683370190505b5090505b841561040657610398600183610a41565b91506103a5600a86610a58565b6103b0906030610a6c565b60f81b8183815181106103c5576103c5610800565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506103ff600a86610a2d565b9450610387565b949350505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461043257600080fd5b919050565b60008060006060848603121561044c57600080fd5b6104558461040e565b92506104636020850161040e565b9150604084013590509250925092565b60005b8381101561048e578181015183820152602001610476565b8381111561049d576000848401525b50505050565b600081518084526104bb816020860160208601610473565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061050060208301846104a3565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561055957610559610507565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156105a6576105a6610507565b604052919050565b600060208083850312156105c157600080fd5b823567ffffffffffffffff808211156105d957600080fd5b818501915085601f8301126105ed57600080fd5b8135818111156105ff576105ff610507565b8060051b61060e85820161055f565b918252838101850191858101908984111561062857600080fd5b86860192505b8383101561072a578235858111156106465760008081fd5b860160607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828d03810182131561067d5760008081fd5b610685610536565b6106908b850161040e565b81526040848101358c8301529284013592898411156106af5760008081fd5b83850194508e603f8601126106c657600093508384fd5b8b8501359350898411156106dc576106dc610507565b6106ec8c84601f8701160161055f565b92508383528e818587010111156107035760008081fd5b838186018d85013760009383018c019390935291820152835250918601919086019061062e565b9998505050505050505050565b600181811c9082168061074b57607f821691505b602082108103610784577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000845161079c818460208901610473565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516107d8816001850160208a01610473565b600192019182015283516107f3816002840160208801610473565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b601f8211156102cc57600081815260208120601f850160051c810160208610156108565750805b601f850160051c820191505b8181101561087557828155600101610862565b505050505050565b815167ffffffffffffffff81111561089757610897610507565b6108ab816108a58454610737565b8461082f565b602080601f8311600181146108fe57600084156108c85750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610875565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561094b5788860151825594840194600190910190840161092c565b508582101561098757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109f7576109f7610997565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610a3c57610a3c6109fe565b500490565b600082821015610a5357610a53610997565b500390565b600082610a6757610a676109fe565b500690565b60008219821115610a7f57610a7f610997565b50019056fea26469706673582212204abcd56633387050a41a0ae027bbf9077ae2fb5080fa84124e2aa381adb3f98964736f6c634300080f0033", "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806329b42cb51461005157806354fd4d501461007a5780635eb5ea1014610082578063702b9dee14610097575b600080fd5b61006461005f36600461046c565b6100aa565b604051610071919061051e565b60405180910390f35b610064610154565b610095610090366004610538565b6101f7565b005b6100956100a5366004610687565b61025a565b60006020818152938152604080822085529281528281209093528252902080546100d3906106de565b80601f01602080910402602001604051908101604052809291908181526020018280546100ff906106de565b801561014c5780601f106101215761010080835404028352916020019161014c565b820191906000526020600020905b81548152906001019060200180831161012f57829003601f168201915b505050505081565b606061017f7f0000000000000000000000000000000000000000000000000000000000000000610306565b6101a87f0000000000000000000000000000000000000000000000000000000000000000610306565b6101d17f0000000000000000000000000000000000000000000000000000000000000000610306565b6040516020016101e393929190610731565b604051602081830303815290604052905090565b8060005b81811015610254576000848483818110610217576102176107a7565b905060200281019061022991906107d6565b61023290610814565b905061024b81600001518260200151836040015161025a565b506001016101fb565b50505050565b3360009081526020818152604080832073ffffffffffffffffffffffffffffffffffffffff871684528252808320858452909152902061029a82826108df565b50818373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f28710dfecab43d1e29e02aa56b2e1e610c0bae19135c9cf7a83a1adb6df96d85846040516102f9919061051e565b60405180910390a4505050565b60608160000361034957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610373578061035d81610a28565b915061036c9050600a83610a8f565b915061034d565b60008167ffffffffffffffff81111561038e5761038e6105ad565b6040519080825280601f01601f1916602001820160405280156103b8576020820181803683370190505b5090505b841561043b576103cd600183610aa3565b91506103da600a86610aba565b6103e5906030610ace565b60f81b8183815181106103fa576103fa6107a7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610434600a86610a8f565b94506103bc565b949350505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461046757600080fd5b919050565b60008060006060848603121561048157600080fd5b61048a84610443565b925061049860208501610443565b9150604084013590509250925092565b60005b838110156104c35781810151838201526020016104ab565b838111156102545750506000910152565b600081518084526104ec8160208601602086016104a8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061053160208301846104d4565b9392505050565b6000806020838503121561054b57600080fd5b823567ffffffffffffffff8082111561056357600080fd5b818501915085601f83011261057757600080fd5b81358181111561058657600080fd5b8660208260051b850101111561059b57600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126105ed57600080fd5b813567ffffffffffffffff80821115610608576106086105ad565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561064e5761064e6105ad565b8160405283815286602085880101111561066757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561069c57600080fd5b6106a584610443565b925060208401359150604084013567ffffffffffffffff8111156106c857600080fd5b6106d4868287016105dc565b9150509250925092565b600181811c908216806106f257607f821691505b60208210810361072b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600084516107438184602089016104a8565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855161077f816001850160208a016104a8565b6001920191820152835161079a8160028401602088016104a8565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261080a57600080fd5b9190910192915050565b60006060823603121561082657600080fd5b6040516060810167ffffffffffffffff828210818311171561084a5761084a6105ad565b8160405261085785610443565b835260208501356020840152604085013591508082111561087757600080fd5b50610884368286016105dc565b60408301525092915050565b601f8211156108da57600081815260208120601f850160051c810160208610156108b75750805b601f850160051c820191505b818110156108d6578281556001016108c3565b5050505b505050565b815167ffffffffffffffff8111156108f9576108f96105ad565b61090d8161090784546106de565b84610890565b602080601f831160018114610960576000841561092a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556108d6565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156109ad5788860151825594840194600190910190840161098e565b50858210156109e957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610a5957610a596109f9565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610a9e57610a9e610a60565b500490565b600082821015610ab557610ab56109f9565b500390565b600082610ac957610ac9610a60565b500690565b60008219821115610ae157610ae16109f9565b50019056fea2646970667358221220bfd4abacc1c2510682b093eea8745255cdd9f45c5b16c168540522a65ddc1f3264736f6c634300080f0033",
"devdoc": { "devdoc": {
"author": "Optimism CollectiveGitcoin", "author": "Optimism CollectiveGitcoin",
"events": { "events": {
...@@ -151,8 +174,15 @@ ...@@ -151,8 +174,15 @@
"_attestations": "An array of attestation data." "_attestations": "An array of attestation data."
} }
}, },
"attest(address,bytes32,bytes)": {
"params": {
"_about": "Address that the attestation is about.",
"_key": "A key used to namespace the attestation.",
"_val": "An arbitrary value stored as part of the attestation."
}
},
"constructor": { "constructor": {
"custom:semver": "1.0.0" "custom:semver": "1.1.0"
}, },
"version()": { "version()": {
"returns": { "returns": {
...@@ -174,6 +204,9 @@ ...@@ -174,6 +204,9 @@
"attest((address,bytes32,bytes)[])": { "attest((address,bytes32,bytes)[])": {
"notice": "Allows anyone to create attestations." "notice": "Allows anyone to create attestations."
}, },
"attest(address,bytes32,bytes)": {
"notice": "Allows anyone to create an attestation."
},
"attestations(address,address,bytes32)": { "attestations(address,address,bytes32)": {
"notice": "Maps addresses to attestations. Creator => About => Key => Value." "notice": "Maps addresses to attestations. Creator => About => Key => Value."
}, },
...@@ -187,7 +220,7 @@ ...@@ -187,7 +220,7 @@
"storageLayout": { "storageLayout": {
"storage": [ "storage": [
{ {
"astId": 8191, "astId": 2135,
"contract": "contracts/universal/op-nft/AttestationStation.sol:AttestationStation", "contract": "contracts/universal/op-nft/AttestationStation.sol:AttestationStation",
"label": "attestations", "label": "attestations",
"offset": 0, "offset": 0,
......
{
"language": "Solidity",
"sources": {
"contracts/universal/op-nft/AttestationStation.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\";\n\n/**\n * @title AttestationStation\n * @author Optimism Collective\n * @author Gitcoin\n * @notice Where attestations live.\n */\ncontract AttestationStation is Semver {\n /**\n * @notice Struct representing data that is being attested.\n *\n * @custom:field about Address for which the attestation is about.\n * @custom:field key A bytes32 key for the attestation.\n * @custom:field val The attestation as arbitrary bytes.\n */\n struct AttestationData {\n address about;\n bytes32 key;\n bytes val;\n }\n\n /**\n * @notice Maps addresses to attestations. Creator => About => Key => Value.\n */\n mapping(address => mapping(address => mapping(bytes32 => bytes))) public attestations;\n\n /**\n * @notice Emitted when Attestation is created.\n *\n * @param creator Address that made the attestation.\n * @param about Address attestation is about.\n * @param key Key of the attestation.\n * @param val Value of the attestation.\n */\n event AttestationCreated(\n address indexed creator,\n address indexed about,\n bytes32 indexed key,\n bytes val\n );\n\n /**\n * @custom:semver 1.1.0\n */\n constructor() Semver(1, 1, 0) {}\n\n /**\n * @notice Allows anyone to create an attestation.\n *\n * @param _about Address that the attestation is about.\n * @param _key A key used to namespace the attestation.\n * @param _val An arbitrary value stored as part of the attestation.\n */\n function attest(\n address _about,\n bytes32 _key,\n bytes memory _val\n ) public {\n attestations[msg.sender][_about][_key] = _val;\n\n emit AttestationCreated(msg.sender, _about, _key, _val);\n }\n\n /**\n * @notice Allows anyone to create attestations.\n *\n * @param _attestations An array of attestation data.\n */\n function attest(AttestationData[] calldata _attestations) external {\n uint256 length = _attestations.length;\n for (uint256 i = 0; i < length; ) {\n AttestationData memory attestation = _attestations[i];\n\n attest(attestation.about, attestation.key, attestation.val);\n\n unchecked {\n ++i;\n }\n }\n }\n}\n"
},
"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title Semver\n * @notice Semver is a simple contract for managing contract versions.\n */\ncontract Semver {\n /**\n * @notice Contract version number (major).\n */\n uint256 private immutable MAJOR_VERSION;\n\n /**\n * @notice Contract version number (minor).\n */\n uint256 private immutable MINOR_VERSION;\n\n /**\n * @notice Contract version number (patch).\n */\n uint256 private immutable PATCH_VERSION;\n\n /**\n * @param _major Version number (major).\n * @param _minor Version number (minor).\n * @param _patch Version number (patch).\n */\n constructor(\n uint256 _major,\n uint256 _minor,\n uint256 _patch\n ) {\n MAJOR_VERSION = _major;\n MINOR_VERSION = _minor;\n PATCH_VERSION = _patch;\n }\n\n /**\n * @notice Returns the full semver contract version.\n *\n * @return Semver contract version as a string.\n */\n function version() public view returns (string memory) {\n return\n string(\n abi.encodePacked(\n Strings.toString(MAJOR_VERSION),\n \".\",\n Strings.toString(MINOR_VERSION),\n \".\",\n Strings.toString(PATCH_VERSION)\n )\n );\n }\n}\n"
},
"@openzeppelin/contracts/utils/Strings.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
},
"contracts/universal/op-nft/Optimist.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\";\nimport {\n ERC721BurnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\";\nimport { AttestationStation } from \"./AttestationStation.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @author Optimism Collective\n * @author Gitcoin\n * @title Optimist\n * @notice A Soul Bound Token for real humans only(tm).\n */\ncontract Optimist is ERC721BurnableUpgradeable, Semver {\n /**\n * @notice Address of the AttestationStation contract.\n */\n AttestationStation public immutable ATTESTATION_STATION;\n\n /**\n * @notice Attestor who attests to baseURI and allowlist.\n */\n address public immutable ATTESTOR;\n\n /**\n * @custom:semver 1.0.0\n * @param _name Token name.\n * @param _symbol Token symbol.\n * @param _attestor Address of the attestor.\n * @param _attestationStation Address of the AttestationStation contract.\n */\n constructor(\n string memory _name,\n string memory _symbol,\n address _attestor,\n AttestationStation _attestationStation\n ) Semver(1, 0, 0) {\n ATTESTOR = _attestor;\n ATTESTATION_STATION = _attestationStation;\n initialize(_name, _symbol);\n }\n\n /**\n * @notice Initializes the Optimist contract.\n *\n * @param _name Token name.\n * @param _symbol Token symbol.\n */\n function initialize(string memory _name, string memory _symbol) public initializer {\n __ERC721_init(_name, _symbol);\n __ERC721Burnable_init();\n }\n\n /**\n * @notice Allows an address to mint an Optimist NFT. Token ID is the uint256 representation\n * of the recipient's address. Recipients must be permitted to mint, eventually anyone\n * will be able to mint. One token per address.\n *\n * @param _recipient Address of the token recipient.\n */\n function mint(address _recipient) public {\n require(isOnAllowList(_recipient), \"Optimist: address is not on allowList\");\n _safeMint(_recipient, tokenIdOfAddress(_recipient));\n }\n\n /**\n * @notice Returns the baseURI for all tokens.\n *\n * @return BaseURI for all tokens.\n */\n function baseURI() public view returns (string memory) {\n return\n string(\n abi.encodePacked(\n ATTESTATION_STATION.attestations(\n ATTESTOR,\n address(this),\n bytes32(\"optimist.base-uri\")\n )\n )\n );\n }\n\n /**\n * @notice Returns the token URI for a given token by ID\n *\n * @param _tokenId Token ID to query.\n\n * @return Token URI for the given token by ID.\n */\n function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {\n return\n string(\n abi.encodePacked(\n baseURI(),\n \"/\",\n // Properly format the token ID as a 20 byte hex string (address).\n Strings.toHexString(_tokenId, 20),\n \".json\"\n )\n );\n }\n\n /**\n * @notice Checks whether a given address is allowed to mint the Optimist NFT yet. Since the\n * Optimist NFT will also be used as part of the Citizens House, mints are currently\n * restricted. Eventually anyone will be able to mint.\n *\n * @return Whether or not the address is allowed to mint yet.\n */\n function isOnAllowList(address _recipient) public view returns (bool) {\n return\n ATTESTATION_STATION\n .attestations(ATTESTOR, _recipient, bytes32(\"optimist.can-mint\"))\n .length > 0;\n }\n\n /**\n * @notice Returns the token ID for the token owned by a given address. This is the uint256\n * representation of the given address.\n *\n * @return Token ID for the token owned by the given address.\n */\n function tokenIdOfAddress(address _owner) public pure returns (uint256) {\n return uint256(uint160(_owner));\n }\n\n /**\n * @notice Disabled for the Optimist NFT (Soul Bound Token).\n */\n function approve(address, uint256) public pure override {\n revert(\"Optimist: soul bound token\");\n }\n\n /**\n * @notice Disabled for the Optimist NFT (Soul Bound Token).\n */\n function setApprovalForAll(address, bool) public virtual override {\n revert(\"Optimist: soul bound token\");\n }\n\n /**\n * @notice Prevents transfers of the Optimist NFT (Soul Bound Token).\n *\n * @param _from Address of the token sender.\n * @param _to Address of the token recipient.\n */\n function _beforeTokenTransfer(\n address _from,\n address _to,\n uint256\n ) internal virtual override {\n require(_from == address(0) || _to == address(0), \"Optimist: soul bound token\");\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n function __ERC721Burnable_init() internal onlyInitializing {\n }\n\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Burns `tokenId`. See {ERC721-_burn}.\n *\n * Requirements:\n *\n * - The caller must own `tokenId` or be an approved operator.\n */\n function burn(uint256 tokenId) public virtual {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _burn(tokenId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 10000
},
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.gasEstimates"
],
"": [
"ast"
]
}
},
"metadata": {
"useLiteralContent": true
}
}
}
\ No newline at end of file
{ {
"address": "0x1BEb19F1685ddF2F774884902119Fa2FA5d8f509", "address": "0xbeD744818e96AAD8a51324291a6f6Cb20A0c22be",
"abi": [ "abi": [
{ {
"inputs": [], "inputs": [],
...@@ -67,6 +67,29 @@ ...@@ -67,6 +67,29 @@
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "address",
"name": "_about",
"type": "address"
},
{
"internalType": "bytes32",
"name": "_key",
"type": "bytes32"
},
{
"internalType": "bytes",
"name": "_val",
"type": "bytes"
}
],
"name": "attest",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
...@@ -110,28 +133,28 @@ ...@@ -110,28 +133,28 @@
"type": "function" "type": "function"
} }
], ],
"transactionHash": "0x84a56c4b4090faef9131650fbbcf38e128e9d98ce77a06ca2e7485c8a137b9a6", "transactionHash": "0x0272013b1d20b4b8e2b8153867389c1c75cbbd5c50e564ee71a62dbfcc35f062",
"receipt": { "receipt": {
"to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", "from": "0x956a5152D0f498dBA0c5966577bb44262F8F7078",
"contractAddress": null, "contractAddress": null,
"transactionIndex": 0, "transactionIndex": 0,
"gasUsed": "645110", "gasUsed": "666309",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0xe588af2eaf9e982580a846beb0f8030a896400431219ce0deca38524defc6324", "blockHash": "0x6d539badaadce9732f2f79e1ceaee94499dd0003d42862324ff334bd7e7e6e68",
"transactionHash": "0x84a56c4b4090faef9131650fbbcf38e128e9d98ce77a06ca2e7485c8a137b9a6", "transactionHash": "0x0272013b1d20b4b8e2b8153867389c1c75cbbd5c50e564ee71a62dbfcc35f062",
"logs": [], "logs": [],
"blockNumber": 49669933, "blockNumber": 70643992,
"cumulativeGasUsed": "645110", "cumulativeGasUsed": "666309",
"status": 1, "status": 1,
"byzantium": true "byzantium": true
}, },
"args": [], "args": [],
"numDeployments": 1, "numDeployments": 2,
"solcInputHash": "45837d34ff24b9cb2ae34232b60ea874", "solcInputHash": "3aa2ad7d005d9515a1f12df8da17d178",
"metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"about\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"val\",\"type\":\"bytes\"}],\"name\":\"AttestationCreated\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"about\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"val\",\"type\":\"bytes\"}],\"internalType\":\"struct AttestationStation.AttestationData[]\",\"name\":\"_attestations\",\"type\":\"tuple[]\"}],\"name\":\"attest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"attestations\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Optimism CollectiveGitcoin\",\"events\":{\"AttestationCreated(address,address,bytes32,bytes)\":{\"params\":{\"about\":\"Address attestation is about.\",\"creator\":\"Address that made the attestation.\",\"key\":\"Key of the attestation.\",\"val\":\"Value of the attestation.\"}}},\"kind\":\"dev\",\"methods\":{\"attest((address,bytes32,bytes)[])\":{\"params\":{\"_attestations\":\"An array of attestation data.\"}},\"constructor\":{\"custom:semver\":\"1.0.0\"},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"AttestationStation\",\"version\":1},\"userdoc\":{\"events\":{\"AttestationCreated(address,address,bytes32,bytes)\":{\"notice\":\"Emitted when Attestation is created.\"}},\"kind\":\"user\",\"methods\":{\"attest((address,bytes32,bytes)[])\":{\"notice\":\"Allows anyone to create attestations.\"},\"attestations(address,address,bytes32)\":{\"notice\":\"Maps addresses to attestations. Creator => About => Key => Value.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"Where attestations live.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/op-nft/AttestationStation.sol\":\"AttestationStation\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.15;\\n\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/**\\n * @title Semver\\n * @notice Semver is a simple contract for managing contract versions.\\n */\\ncontract Semver {\\n /**\\n * @notice Contract version number (major).\\n */\\n uint256 private immutable MAJOR_VERSION;\\n\\n /**\\n * @notice Contract version number (minor).\\n */\\n uint256 private immutable MINOR_VERSION;\\n\\n /**\\n * @notice Contract version number (patch).\\n */\\n uint256 private immutable PATCH_VERSION;\\n\\n /**\\n * @param _major Version number (major).\\n * @param _minor Version number (minor).\\n * @param _patch Version number (patch).\\n */\\n constructor(\\n uint256 _major,\\n uint256 _minor,\\n uint256 _patch\\n ) {\\n MAJOR_VERSION = _major;\\n MINOR_VERSION = _minor;\\n PATCH_VERSION = _patch;\\n }\\n\\n /**\\n * @notice Returns the full semver contract version.\\n *\\n * @return Semver contract version as a string.\\n */\\n function version() public view returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n Strings.toString(MAJOR_VERSION),\\n \\\".\\\",\\n Strings.toString(MINOR_VERSION),\\n \\\".\\\",\\n Strings.toString(PATCH_VERSION)\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x979b13465de4996a1105850abbf48abe7f71d5e18a8d4af318597ee14c165fdf\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/universal/op-nft/AttestationStation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\n\\n/**\\n * @title AttestationStation\\n * @author Optimism Collective\\n * @author Gitcoin\\n * @notice Where attestations live.\\n */\\ncontract AttestationStation is Semver {\\n /**\\n * @notice Struct representing data that is being attested.\\n *\\n * @custom:field about Address for which the attestation is about.\\n * @custom:field key A bytes32 key for the attestation.\\n * @custom:field val The attestation as arbitrary bytes.\\n */\\n struct AttestationData {\\n address about;\\n bytes32 key;\\n bytes val;\\n }\\n\\n /**\\n * @notice Maps addresses to attestations. Creator => About => Key => Value.\\n */\\n mapping(address => mapping(address => mapping(bytes32 => bytes))) public attestations;\\n\\n /**\\n * @notice Emitted when Attestation is created.\\n *\\n * @param creator Address that made the attestation.\\n * @param about Address attestation is about.\\n * @param key Key of the attestation.\\n * @param val Value of the attestation.\\n */\\n event AttestationCreated(\\n address indexed creator,\\n address indexed about,\\n bytes32 indexed key,\\n bytes val\\n );\\n\\n /**\\n * @custom:semver 1.0.0\\n */\\n constructor() Semver(1, 0, 0) {}\\n\\n /**\\n * @notice Allows anyone to create attestations.\\n *\\n * @param _attestations An array of attestation data.\\n */\\n function attest(AttestationData[] memory _attestations) public {\\n uint256 length = _attestations.length;\\n for (uint256 i = 0; i < length; ) {\\n AttestationData memory attestation = _attestations[i];\\n attestations[msg.sender][attestation.about][attestation.key] = attestation.val;\\n\\n emit AttestationCreated(\\n msg.sender,\\n attestation.about,\\n attestation.key,\\n attestation.val\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x670fde721c291828c3f6343a40bb315dbbcc5e4411125158892ffe54459d69b7\",\"license\":\"MIT\"}},\"version\":1}", "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"about\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"val\",\"type\":\"bytes\"}],\"name\":\"AttestationCreated\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"about\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"val\",\"type\":\"bytes\"}],\"internalType\":\"struct AttestationStation.AttestationData[]\",\"name\":\"_attestations\",\"type\":\"tuple[]\"}],\"name\":\"attest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_about\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_val\",\"type\":\"bytes\"}],\"name\":\"attest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"attestations\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Optimism CollectiveGitcoin\",\"events\":{\"AttestationCreated(address,address,bytes32,bytes)\":{\"params\":{\"about\":\"Address attestation is about.\",\"creator\":\"Address that made the attestation.\",\"key\":\"Key of the attestation.\",\"val\":\"Value of the attestation.\"}}},\"kind\":\"dev\",\"methods\":{\"attest((address,bytes32,bytes)[])\":{\"params\":{\"_attestations\":\"An array of attestation data.\"}},\"attest(address,bytes32,bytes)\":{\"params\":{\"_about\":\"Address that the attestation is about.\",\"_key\":\"A key used to namespace the attestation.\",\"_val\":\"An arbitrary value stored as part of the attestation.\"}},\"constructor\":{\"custom:semver\":\"1.1.0\"},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"AttestationStation\",\"version\":1},\"userdoc\":{\"events\":{\"AttestationCreated(address,address,bytes32,bytes)\":{\"notice\":\"Emitted when Attestation is created.\"}},\"kind\":\"user\",\"methods\":{\"attest((address,bytes32,bytes)[])\":{\"notice\":\"Allows anyone to create attestations.\"},\"attest(address,bytes32,bytes)\":{\"notice\":\"Allows anyone to create an attestation.\"},\"attestations(address,address,bytes32)\":{\"notice\":\"Maps addresses to attestations. Creator => About => Key => Value.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"Where attestations live.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/op-nft/AttestationStation.sol\":\"AttestationStation\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.15;\\n\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/**\\n * @title Semver\\n * @notice Semver is a simple contract for managing contract versions.\\n */\\ncontract Semver {\\n /**\\n * @notice Contract version number (major).\\n */\\n uint256 private immutable MAJOR_VERSION;\\n\\n /**\\n * @notice Contract version number (minor).\\n */\\n uint256 private immutable MINOR_VERSION;\\n\\n /**\\n * @notice Contract version number (patch).\\n */\\n uint256 private immutable PATCH_VERSION;\\n\\n /**\\n * @param _major Version number (major).\\n * @param _minor Version number (minor).\\n * @param _patch Version number (patch).\\n */\\n constructor(\\n uint256 _major,\\n uint256 _minor,\\n uint256 _patch\\n ) {\\n MAJOR_VERSION = _major;\\n MINOR_VERSION = _minor;\\n PATCH_VERSION = _patch;\\n }\\n\\n /**\\n * @notice Returns the full semver contract version.\\n *\\n * @return Semver contract version as a string.\\n */\\n function version() public view returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n Strings.toString(MAJOR_VERSION),\\n \\\".\\\",\\n Strings.toString(MINOR_VERSION),\\n \\\".\\\",\\n Strings.toString(PATCH_VERSION)\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x979b13465de4996a1105850abbf48abe7f71d5e18a8d4af318597ee14c165fdf\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/universal/op-nft/AttestationStation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\n\\n/**\\n * @title AttestationStation\\n * @author Optimism Collective\\n * @author Gitcoin\\n * @notice Where attestations live.\\n */\\ncontract AttestationStation is Semver {\\n /**\\n * @notice Struct representing data that is being attested.\\n *\\n * @custom:field about Address for which the attestation is about.\\n * @custom:field key A bytes32 key for the attestation.\\n * @custom:field val The attestation as arbitrary bytes.\\n */\\n struct AttestationData {\\n address about;\\n bytes32 key;\\n bytes val;\\n }\\n\\n /**\\n * @notice Maps addresses to attestations. Creator => About => Key => Value.\\n */\\n mapping(address => mapping(address => mapping(bytes32 => bytes))) public attestations;\\n\\n /**\\n * @notice Emitted when Attestation is created.\\n *\\n * @param creator Address that made the attestation.\\n * @param about Address attestation is about.\\n * @param key Key of the attestation.\\n * @param val Value of the attestation.\\n */\\n event AttestationCreated(\\n address indexed creator,\\n address indexed about,\\n bytes32 indexed key,\\n bytes val\\n );\\n\\n /**\\n * @custom:semver 1.1.0\\n */\\n constructor() Semver(1, 1, 0) {}\\n\\n /**\\n * @notice Allows anyone to create an attestation.\\n *\\n * @param _about Address that the attestation is about.\\n * @param _key A key used to namespace the attestation.\\n * @param _val An arbitrary value stored as part of the attestation.\\n */\\n function attest(\\n address _about,\\n bytes32 _key,\\n bytes memory _val\\n ) public {\\n attestations[msg.sender][_about][_key] = _val;\\n\\n emit AttestationCreated(msg.sender, _about, _key, _val);\\n }\\n\\n /**\\n * @notice Allows anyone to create attestations.\\n *\\n * @param _attestations An array of attestation data.\\n */\\n function attest(AttestationData[] calldata _attestations) external {\\n uint256 length = _attestations.length;\\n for (uint256 i = 0; i < length; ) {\\n AttestationData memory attestation = _attestations[i];\\n\\n attest(attestation.about, attestation.key, attestation.val);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x80718fdc09061ea8f8b99a0b846eee46c5a2a1372dbb0cbc3d40953cb3af19e0\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x60e060405234801561001057600080fd5b5060016080819052600060a081905260c081905280610aba61004a8239600061018f015260006101660152600061013d0152610aba6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806329b42cb51461004657806354fd4d501461006f5780635eb5ea1014610077575b600080fd5b610059610054366004610437565b61008c565b60405161006691906104ed565b60405180910390f35b610059610136565b61008a6100853660046105ae565b6101d9565b005b60006020818152938152604080822085529281528281209093528252902080546100b590610737565b80601f01602080910402602001604051908101604052809291908181526020018280546100e190610737565b801561012e5780601f106101035761010080835404028352916020019161012e565b820191906000526020600020905b81548152906001019060200180831161011157829003601f168201915b505050505081565b60606101617f00000000000000000000000000000000000000000000000000000000000000006102d1565b61018a7f00000000000000000000000000000000000000000000000000000000000000006102d1565b6101b37f00000000000000000000000000000000000000000000000000000000000000006102d1565b6040516020016101c59392919061078a565b604051602081830303815290604052905090565b805160005b818110156102cc5760008382815181106101fa576101fa610800565b602090810291909101810151604080820151336000908152808552828120845173ffffffffffffffffffffffffffffffffffffffff1682528552828120848601518252909452922090925090610250908261087d565b508060200151816000015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f28710dfecab43d1e29e02aa56b2e1e610c0bae19135c9cf7a83a1adb6df96d8584604001516040516102bb91906104ed565b60405180910390a4506001016101de565b505050565b60608160000361031457505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561033e5780610328816109c6565b91506103379050600a83610a2d565b9150610318565b60008167ffffffffffffffff81111561035957610359610507565b6040519080825280601f01601f191660200182016040528015610383576020820181803683370190505b5090505b841561040657610398600183610a41565b91506103a5600a86610a58565b6103b0906030610a6c565b60f81b8183815181106103c5576103c5610800565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506103ff600a86610a2d565b9450610387565b949350505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461043257600080fd5b919050565b60008060006060848603121561044c57600080fd5b6104558461040e565b92506104636020850161040e565b9150604084013590509250925092565b60005b8381101561048e578181015183820152602001610476565b8381111561049d576000848401525b50505050565b600081518084526104bb816020860160208601610473565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061050060208301846104a3565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561055957610559610507565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156105a6576105a6610507565b604052919050565b600060208083850312156105c157600080fd5b823567ffffffffffffffff808211156105d957600080fd5b818501915085601f8301126105ed57600080fd5b8135818111156105ff576105ff610507565b8060051b61060e85820161055f565b918252838101850191858101908984111561062857600080fd5b86860192505b8383101561072a578235858111156106465760008081fd5b860160607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828d03810182131561067d5760008081fd5b610685610536565b6106908b850161040e565b81526040848101358c8301529284013592898411156106af5760008081fd5b83850194508e603f8601126106c657600093508384fd5b8b8501359350898411156106dc576106dc610507565b6106ec8c84601f8701160161055f565b92508383528e818587010111156107035760008081fd5b838186018d85013760009383018c019390935291820152835250918601919086019061062e565b9998505050505050505050565b600181811c9082168061074b57607f821691505b602082108103610784577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000845161079c818460208901610473565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516107d8816001850160208a01610473565b600192019182015283516107f3816002840160208801610473565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b601f8211156102cc57600081815260208120601f850160051c810160208610156108565750805b601f850160051c820191505b8181101561087557828155600101610862565b505050505050565b815167ffffffffffffffff81111561089757610897610507565b6108ab816108a58454610737565b8461082f565b602080601f8311600181146108fe57600084156108c85750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610875565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561094b5788860151825594840194600190910190840161092c565b508582101561098757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109f7576109f7610997565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610a3c57610a3c6109fe565b500490565b600082821015610a5357610a53610997565b500390565b600082610a6757610a676109fe565b500690565b60008219821115610a7f57610a7f610997565b50019056fea26469706673582212204abcd56633387050a41a0ae027bbf9077ae2fb5080fa84124e2aa381adb3f98964736f6c634300080f0033", "bytecode": "0x60e060405234801561001057600080fd5b506001608081905260a052600060c05260805160a05160c051610b1c61004f60003960006101ad015260006101840152600061015b0152610b1c6000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806329b42cb51461005157806354fd4d501461007a5780635eb5ea1014610082578063702b9dee14610097575b600080fd5b61006461005f36600461046c565b6100aa565b604051610071919061051e565b60405180910390f35b610064610154565b610095610090366004610538565b6101f7565b005b6100956100a5366004610687565b61025a565b60006020818152938152604080822085529281528281209093528252902080546100d3906106de565b80601f01602080910402602001604051908101604052809291908181526020018280546100ff906106de565b801561014c5780601f106101215761010080835404028352916020019161014c565b820191906000526020600020905b81548152906001019060200180831161012f57829003601f168201915b505050505081565b606061017f7f0000000000000000000000000000000000000000000000000000000000000000610306565b6101a87f0000000000000000000000000000000000000000000000000000000000000000610306565b6101d17f0000000000000000000000000000000000000000000000000000000000000000610306565b6040516020016101e393929190610731565b604051602081830303815290604052905090565b8060005b81811015610254576000848483818110610217576102176107a7565b905060200281019061022991906107d6565b61023290610814565b905061024b81600001518260200151836040015161025a565b506001016101fb565b50505050565b3360009081526020818152604080832073ffffffffffffffffffffffffffffffffffffffff871684528252808320858452909152902061029a82826108df565b50818373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f28710dfecab43d1e29e02aa56b2e1e610c0bae19135c9cf7a83a1adb6df96d85846040516102f9919061051e565b60405180910390a4505050565b60608160000361034957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610373578061035d81610a28565b915061036c9050600a83610a8f565b915061034d565b60008167ffffffffffffffff81111561038e5761038e6105ad565b6040519080825280601f01601f1916602001820160405280156103b8576020820181803683370190505b5090505b841561043b576103cd600183610aa3565b91506103da600a86610aba565b6103e5906030610ace565b60f81b8183815181106103fa576103fa6107a7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610434600a86610a8f565b94506103bc565b949350505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461046757600080fd5b919050565b60008060006060848603121561048157600080fd5b61048a84610443565b925061049860208501610443565b9150604084013590509250925092565b60005b838110156104c35781810151838201526020016104ab565b838111156102545750506000910152565b600081518084526104ec8160208601602086016104a8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061053160208301846104d4565b9392505050565b6000806020838503121561054b57600080fd5b823567ffffffffffffffff8082111561056357600080fd5b818501915085601f83011261057757600080fd5b81358181111561058657600080fd5b8660208260051b850101111561059b57600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126105ed57600080fd5b813567ffffffffffffffff80821115610608576106086105ad565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561064e5761064e6105ad565b8160405283815286602085880101111561066757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561069c57600080fd5b6106a584610443565b925060208401359150604084013567ffffffffffffffff8111156106c857600080fd5b6106d4868287016105dc565b9150509250925092565b600181811c908216806106f257607f821691505b60208210810361072b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600084516107438184602089016104a8565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855161077f816001850160208a016104a8565b6001920191820152835161079a8160028401602088016104a8565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261080a57600080fd5b9190910192915050565b60006060823603121561082657600080fd5b6040516060810167ffffffffffffffff828210818311171561084a5761084a6105ad565b8160405261085785610443565b835260208501356020840152604085013591508082111561087757600080fd5b50610884368286016105dc565b60408301525092915050565b601f8211156108da57600081815260208120601f850160051c810160208610156108b75750805b601f850160051c820191505b818110156108d6578281556001016108c3565b5050505b505050565b815167ffffffffffffffff8111156108f9576108f96105ad565b61090d8161090784546106de565b84610890565b602080601f831160018114610960576000841561092a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556108d6565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156109ad5788860151825594840194600190910190840161098e565b50858210156109e957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610a5957610a596109f9565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610a9e57610a9e610a60565b500490565b600082821015610ab557610ab56109f9565b500390565b600082610ac957610ac9610a60565b500690565b60008219821115610ae157610ae16109f9565b50019056fea2646970667358221220bfd4abacc1c2510682b093eea8745255cdd9f45c5b16c168540522a65ddc1f3264736f6c634300080f0033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806329b42cb51461004657806354fd4d501461006f5780635eb5ea1014610077575b600080fd5b610059610054366004610437565b61008c565b60405161006691906104ed565b60405180910390f35b610059610136565b61008a6100853660046105ae565b6101d9565b005b60006020818152938152604080822085529281528281209093528252902080546100b590610737565b80601f01602080910402602001604051908101604052809291908181526020018280546100e190610737565b801561012e5780601f106101035761010080835404028352916020019161012e565b820191906000526020600020905b81548152906001019060200180831161011157829003601f168201915b505050505081565b60606101617f00000000000000000000000000000000000000000000000000000000000000006102d1565b61018a7f00000000000000000000000000000000000000000000000000000000000000006102d1565b6101b37f00000000000000000000000000000000000000000000000000000000000000006102d1565b6040516020016101c59392919061078a565b604051602081830303815290604052905090565b805160005b818110156102cc5760008382815181106101fa576101fa610800565b602090810291909101810151604080820151336000908152808552828120845173ffffffffffffffffffffffffffffffffffffffff1682528552828120848601518252909452922090925090610250908261087d565b508060200151816000015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f28710dfecab43d1e29e02aa56b2e1e610c0bae19135c9cf7a83a1adb6df96d8584604001516040516102bb91906104ed565b60405180910390a4506001016101de565b505050565b60608160000361031457505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561033e5780610328816109c6565b91506103379050600a83610a2d565b9150610318565b60008167ffffffffffffffff81111561035957610359610507565b6040519080825280601f01601f191660200182016040528015610383576020820181803683370190505b5090505b841561040657610398600183610a41565b91506103a5600a86610a58565b6103b0906030610a6c565b60f81b8183815181106103c5576103c5610800565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506103ff600a86610a2d565b9450610387565b949350505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461043257600080fd5b919050565b60008060006060848603121561044c57600080fd5b6104558461040e565b92506104636020850161040e565b9150604084013590509250925092565b60005b8381101561048e578181015183820152602001610476565b8381111561049d576000848401525b50505050565b600081518084526104bb816020860160208601610473565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061050060208301846104a3565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561055957610559610507565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156105a6576105a6610507565b604052919050565b600060208083850312156105c157600080fd5b823567ffffffffffffffff808211156105d957600080fd5b818501915085601f8301126105ed57600080fd5b8135818111156105ff576105ff610507565b8060051b61060e85820161055f565b918252838101850191858101908984111561062857600080fd5b86860192505b8383101561072a578235858111156106465760008081fd5b860160607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828d03810182131561067d5760008081fd5b610685610536565b6106908b850161040e565b81526040848101358c8301529284013592898411156106af5760008081fd5b83850194508e603f8601126106c657600093508384fd5b8b8501359350898411156106dc576106dc610507565b6106ec8c84601f8701160161055f565b92508383528e818587010111156107035760008081fd5b838186018d85013760009383018c019390935291820152835250918601919086019061062e565b9998505050505050505050565b600181811c9082168061074b57607f821691505b602082108103610784577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000845161079c818460208901610473565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516107d8816001850160208a01610473565b600192019182015283516107f3816002840160208801610473565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b601f8211156102cc57600081815260208120601f850160051c810160208610156108565750805b601f850160051c820191505b8181101561087557828155600101610862565b505050505050565b815167ffffffffffffffff81111561089757610897610507565b6108ab816108a58454610737565b8461082f565b602080601f8311600181146108fe57600084156108c85750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610875565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561094b5788860151825594840194600190910190840161092c565b508582101561098757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109f7576109f7610997565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610a3c57610a3c6109fe565b500490565b600082821015610a5357610a53610997565b500390565b600082610a6757610a676109fe565b500690565b60008219821115610a7f57610a7f610997565b50019056fea26469706673582212204abcd56633387050a41a0ae027bbf9077ae2fb5080fa84124e2aa381adb3f98964736f6c634300080f0033", "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806329b42cb51461005157806354fd4d501461007a5780635eb5ea1014610082578063702b9dee14610097575b600080fd5b61006461005f36600461046c565b6100aa565b604051610071919061051e565b60405180910390f35b610064610154565b610095610090366004610538565b6101f7565b005b6100956100a5366004610687565b61025a565b60006020818152938152604080822085529281528281209093528252902080546100d3906106de565b80601f01602080910402602001604051908101604052809291908181526020018280546100ff906106de565b801561014c5780601f106101215761010080835404028352916020019161014c565b820191906000526020600020905b81548152906001019060200180831161012f57829003601f168201915b505050505081565b606061017f7f0000000000000000000000000000000000000000000000000000000000000000610306565b6101a87f0000000000000000000000000000000000000000000000000000000000000000610306565b6101d17f0000000000000000000000000000000000000000000000000000000000000000610306565b6040516020016101e393929190610731565b604051602081830303815290604052905090565b8060005b81811015610254576000848483818110610217576102176107a7565b905060200281019061022991906107d6565b61023290610814565b905061024b81600001518260200151836040015161025a565b506001016101fb565b50505050565b3360009081526020818152604080832073ffffffffffffffffffffffffffffffffffffffff871684528252808320858452909152902061029a82826108df565b50818373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f28710dfecab43d1e29e02aa56b2e1e610c0bae19135c9cf7a83a1adb6df96d85846040516102f9919061051e565b60405180910390a4505050565b60608160000361034957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610373578061035d81610a28565b915061036c9050600a83610a8f565b915061034d565b60008167ffffffffffffffff81111561038e5761038e6105ad565b6040519080825280601f01601f1916602001820160405280156103b8576020820181803683370190505b5090505b841561043b576103cd600183610aa3565b91506103da600a86610aba565b6103e5906030610ace565b60f81b8183815181106103fa576103fa6107a7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610434600a86610a8f565b94506103bc565b949350505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461046757600080fd5b919050565b60008060006060848603121561048157600080fd5b61048a84610443565b925061049860208501610443565b9150604084013590509250925092565b60005b838110156104c35781810151838201526020016104ab565b838111156102545750506000910152565b600081518084526104ec8160208601602086016104a8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061053160208301846104d4565b9392505050565b6000806020838503121561054b57600080fd5b823567ffffffffffffffff8082111561056357600080fd5b818501915085601f83011261057757600080fd5b81358181111561058657600080fd5b8660208260051b850101111561059b57600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126105ed57600080fd5b813567ffffffffffffffff80821115610608576106086105ad565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561064e5761064e6105ad565b8160405283815286602085880101111561066757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561069c57600080fd5b6106a584610443565b925060208401359150604084013567ffffffffffffffff8111156106c857600080fd5b6106d4868287016105dc565b9150509250925092565b600181811c908216806106f257607f821691505b60208210810361072b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600084516107438184602089016104a8565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855161077f816001850160208a016104a8565b6001920191820152835161079a8160028401602088016104a8565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261080a57600080fd5b9190910192915050565b60006060823603121561082657600080fd5b6040516060810167ffffffffffffffff828210818311171561084a5761084a6105ad565b8160405261085785610443565b835260208501356020840152604085013591508082111561087757600080fd5b50610884368286016105dc565b60408301525092915050565b601f8211156108da57600081815260208120601f850160051c810160208610156108b75750805b601f850160051c820191505b818110156108d6578281556001016108c3565b5050505b505050565b815167ffffffffffffffff8111156108f9576108f96105ad565b61090d8161090784546106de565b84610890565b602080601f831160018114610960576000841561092a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556108d6565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156109ad5788860151825594840194600190910190840161098e565b50858210156109e957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610a5957610a596109f9565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610a9e57610a9e610a60565b500490565b600082821015610ab557610ab56109f9565b500390565b600082610ac957610ac9610a60565b500690565b60008219821115610ae157610ae16109f9565b50019056fea2646970667358221220bfd4abacc1c2510682b093eea8745255cdd9f45c5b16c168540522a65ddc1f3264736f6c634300080f0033",
"devdoc": { "devdoc": {
"author": "Optimism CollectiveGitcoin", "author": "Optimism CollectiveGitcoin",
"events": { "events": {
...@@ -151,8 +174,15 @@ ...@@ -151,8 +174,15 @@
"_attestations": "An array of attestation data." "_attestations": "An array of attestation data."
} }
}, },
"attest(address,bytes32,bytes)": {
"params": {
"_about": "Address that the attestation is about.",
"_key": "A key used to namespace the attestation.",
"_val": "An arbitrary value stored as part of the attestation."
}
},
"constructor": { "constructor": {
"custom:semver": "1.0.0" "custom:semver": "1.1.0"
}, },
"version()": { "version()": {
"returns": { "returns": {
...@@ -174,6 +204,9 @@ ...@@ -174,6 +204,9 @@
"attest((address,bytes32,bytes)[])": { "attest((address,bytes32,bytes)[])": {
"notice": "Allows anyone to create attestations." "notice": "Allows anyone to create attestations."
}, },
"attest(address,bytes32,bytes)": {
"notice": "Allows anyone to create an attestation."
},
"attestations(address,address,bytes32)": { "attestations(address,address,bytes32)": {
"notice": "Maps addresses to attestations. Creator => About => Key => Value." "notice": "Maps addresses to attestations. Creator => About => Key => Value."
}, },
...@@ -187,7 +220,7 @@ ...@@ -187,7 +220,7 @@
"storageLayout": { "storageLayout": {
"storage": [ "storage": [
{ {
"astId": 8191, "astId": 2135,
"contract": "contracts/universal/op-nft/AttestationStation.sol:AttestationStation", "contract": "contracts/universal/op-nft/AttestationStation.sol:AttestationStation",
"label": "attestations", "label": "attestations",
"offset": 0, "offset": 0,
......
{
"language": "Solidity",
"sources": {
"contracts/universal/op-nft/AttestationStation.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\";\n\n/**\n * @title AttestationStation\n * @author Optimism Collective\n * @author Gitcoin\n * @notice Where attestations live.\n */\ncontract AttestationStation is Semver {\n /**\n * @notice Struct representing data that is being attested.\n *\n * @custom:field about Address for which the attestation is about.\n * @custom:field key A bytes32 key for the attestation.\n * @custom:field val The attestation as arbitrary bytes.\n */\n struct AttestationData {\n address about;\n bytes32 key;\n bytes val;\n }\n\n /**\n * @notice Maps addresses to attestations. Creator => About => Key => Value.\n */\n mapping(address => mapping(address => mapping(bytes32 => bytes))) public attestations;\n\n /**\n * @notice Emitted when Attestation is created.\n *\n * @param creator Address that made the attestation.\n * @param about Address attestation is about.\n * @param key Key of the attestation.\n * @param val Value of the attestation.\n */\n event AttestationCreated(\n address indexed creator,\n address indexed about,\n bytes32 indexed key,\n bytes val\n );\n\n /**\n * @custom:semver 1.1.0\n */\n constructor() Semver(1, 1, 0) {}\n\n /**\n * @notice Allows anyone to create an attestation.\n *\n * @param _about Address that the attestation is about.\n * @param _key A key used to namespace the attestation.\n * @param _val An arbitrary value stored as part of the attestation.\n */\n function attest(\n address _about,\n bytes32 _key,\n bytes memory _val\n ) public {\n attestations[msg.sender][_about][_key] = _val;\n\n emit AttestationCreated(msg.sender, _about, _key, _val);\n }\n\n /**\n * @notice Allows anyone to create attestations.\n *\n * @param _attestations An array of attestation data.\n */\n function attest(AttestationData[] calldata _attestations) external {\n uint256 length = _attestations.length;\n for (uint256 i = 0; i < length; ) {\n AttestationData memory attestation = _attestations[i];\n\n attest(attestation.about, attestation.key, attestation.val);\n\n unchecked {\n ++i;\n }\n }\n }\n}\n"
},
"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title Semver\n * @notice Semver is a simple contract for managing contract versions.\n */\ncontract Semver {\n /**\n * @notice Contract version number (major).\n */\n uint256 private immutable MAJOR_VERSION;\n\n /**\n * @notice Contract version number (minor).\n */\n uint256 private immutable MINOR_VERSION;\n\n /**\n * @notice Contract version number (patch).\n */\n uint256 private immutable PATCH_VERSION;\n\n /**\n * @param _major Version number (major).\n * @param _minor Version number (minor).\n * @param _patch Version number (patch).\n */\n constructor(\n uint256 _major,\n uint256 _minor,\n uint256 _patch\n ) {\n MAJOR_VERSION = _major;\n MINOR_VERSION = _minor;\n PATCH_VERSION = _patch;\n }\n\n /**\n * @notice Returns the full semver contract version.\n *\n * @return Semver contract version as a string.\n */\n function version() public view returns (string memory) {\n return\n string(\n abi.encodePacked(\n Strings.toString(MAJOR_VERSION),\n \".\",\n Strings.toString(MINOR_VERSION),\n \".\",\n Strings.toString(PATCH_VERSION)\n )\n );\n }\n}\n"
},
"@openzeppelin/contracts/utils/Strings.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
},
"contracts/universal/op-nft/Optimist.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\";\nimport {\n ERC721BurnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\";\nimport { AttestationStation } from \"./AttestationStation.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @author Optimism Collective\n * @author Gitcoin\n * @title Optimist\n * @notice A Soul Bound Token for real humans only(tm).\n */\ncontract Optimist is ERC721BurnableUpgradeable, Semver {\n /**\n * @notice Address of the AttestationStation contract.\n */\n AttestationStation public immutable ATTESTATION_STATION;\n\n /**\n * @notice Attestor who attests to baseURI and allowlist.\n */\n address public immutable ATTESTOR;\n\n /**\n * @custom:semver 1.0.0\n * @param _name Token name.\n * @param _symbol Token symbol.\n * @param _attestor Address of the attestor.\n * @param _attestationStation Address of the AttestationStation contract.\n */\n constructor(\n string memory _name,\n string memory _symbol,\n address _attestor,\n AttestationStation _attestationStation\n ) Semver(1, 0, 0) {\n ATTESTOR = _attestor;\n ATTESTATION_STATION = _attestationStation;\n initialize(_name, _symbol);\n }\n\n /**\n * @notice Initializes the Optimist contract.\n *\n * @param _name Token name.\n * @param _symbol Token symbol.\n */\n function initialize(string memory _name, string memory _symbol) public initializer {\n __ERC721_init(_name, _symbol);\n __ERC721Burnable_init();\n }\n\n /**\n * @notice Allows an address to mint an Optimist NFT. Token ID is the uint256 representation\n * of the recipient's address. Recipients must be permitted to mint, eventually anyone\n * will be able to mint. One token per address.\n *\n * @param _recipient Address of the token recipient.\n */\n function mint(address _recipient) public {\n require(isOnAllowList(_recipient), \"Optimist: address is not on allowList\");\n _safeMint(_recipient, tokenIdOfAddress(_recipient));\n }\n\n /**\n * @notice Returns the baseURI for all tokens.\n *\n * @return BaseURI for all tokens.\n */\n function baseURI() public view returns (string memory) {\n return\n string(\n abi.encodePacked(\n ATTESTATION_STATION.attestations(\n ATTESTOR,\n address(this),\n bytes32(\"optimist.base-uri\")\n )\n )\n );\n }\n\n /**\n * @notice Returns the token URI for a given token by ID\n *\n * @param _tokenId Token ID to query.\n\n * @return Token URI for the given token by ID.\n */\n function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {\n return\n string(\n abi.encodePacked(\n baseURI(),\n \"/\",\n // Properly format the token ID as a 20 byte hex string (address).\n Strings.toHexString(_tokenId, 20),\n \".json\"\n )\n );\n }\n\n /**\n * @notice Checks whether a given address is allowed to mint the Optimist NFT yet. Since the\n * Optimist NFT will also be used as part of the Citizens House, mints are currently\n * restricted. Eventually anyone will be able to mint.\n *\n * @return Whether or not the address is allowed to mint yet.\n */\n function isOnAllowList(address _recipient) public view returns (bool) {\n return\n ATTESTATION_STATION\n .attestations(ATTESTOR, _recipient, bytes32(\"optimist.can-mint\"))\n .length > 0;\n }\n\n /**\n * @notice Returns the token ID for the token owned by a given address. This is the uint256\n * representation of the given address.\n *\n * @return Token ID for the token owned by the given address.\n */\n function tokenIdOfAddress(address _owner) public pure returns (uint256) {\n return uint256(uint160(_owner));\n }\n\n /**\n * @notice Disabled for the Optimist NFT (Soul Bound Token).\n */\n function approve(address, uint256) public pure override {\n revert(\"Optimist: soul bound token\");\n }\n\n /**\n * @notice Disabled for the Optimist NFT (Soul Bound Token).\n */\n function setApprovalForAll(address, bool) public virtual override {\n revert(\"Optimist: soul bound token\");\n }\n\n /**\n * @notice Prevents transfers of the Optimist NFT (Soul Bound Token).\n *\n * @param _from Address of the token sender.\n * @param _to Address of the token recipient.\n */\n function _beforeTokenTransfer(\n address _from,\n address _to,\n uint256\n ) internal virtual override {\n require(_from == address(0) || _to == address(0), \"Optimist: soul bound token\");\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n function __ERC721Burnable_init() internal onlyInitializing {\n }\n\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Burns `tokenId`. See {ERC721-_burn}.\n *\n * Requirements:\n *\n * - The caller must own `tokenId` or be an approved operator.\n */\n function burn(uint256 tokenId) public virtual {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _burn(tokenId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 10000
},
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.gasEstimates"
],
"": [
"ast"
]
}
},
"metadata": {
"useLiteralContent": true
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment