From 2aa513d0f847eb43570f05faee688e2abb48417d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n?= Date: Wed, 28 Aug 2024 12:26:42 -0300 Subject: [PATCH] feat: deploy batch mint contracts --- .../999_helpers/01_deploy_batch_mint.ts | 22 + ...Abb4B452Dd9f74476cE49ee197a1Af6E803ea.json | 420 ++++++++++ ...fe22691c811ea339D9B73150e6911a5343DcA.json | 420 ++++++++++ .../8647b3c46fdd7d95d4038ddf2cc1e589.json | 785 ++++++++++++++++++ packages/core/hardhat.config.ts | 16 +- 5 files changed, 1656 insertions(+), 7 deletions(-) create mode 100644 packages/core/deploy_polygon/999_helpers/01_deploy_batch_mint.ts create mode 100644 packages/core/deployments/amoy/Batch-0xC9bAbb4B452Dd9f74476cE49ee197a1Af6E803ea.json create mode 100644 packages/core/deployments/polygon/Batch-0x7A9fe22691c811ea339D9B73150e6911a5343DcA.json create mode 100644 packages/core/deployments/polygon/solcInputs/8647b3c46fdd7d95d4038ddf2cc1e589.json diff --git a/packages/core/deploy_polygon/999_helpers/01_deploy_batch_mint.ts b/packages/core/deploy_polygon/999_helpers/01_deploy_batch_mint.ts new file mode 100644 index 0000000000..f11439f876 --- /dev/null +++ b/packages/core/deploy_polygon/999_helpers/01_deploy_batch_mint.ts @@ -0,0 +1,22 @@ +import { DeployFunction } from 'hardhat-deploy/types'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const { deployments, getNamedAccounts } = hre; + const { deploy, execute, read } = deployments; + const { deployer, sandboxAccount } = await getNamedAccounts(); + const batch = await deploy(`Batch-${sandboxAccount}`, { + contract: `Batch`, + from: deployer, + args: [sandboxAccount], + log: true, + skipIfAlreadyDeployed: true, + }); + const isMinter = await read("PolygonLand", "isMinter", batch.address); + if (!isMinter) { + const admin = await read("PolygonLand", "getAdmin"); + await execute("PolygonLand", { from: admin, log: true }, "setMinter", batch.address, true); + } +}; +export default func; +func.tags = ['DeployerBatchMint', 'DeployerBatchMint_deploy']; diff --git a/packages/core/deployments/amoy/Batch-0xC9bAbb4B452Dd9f74476cE49ee197a1Af6E803ea.json b/packages/core/deployments/amoy/Batch-0xC9bAbb4B452Dd9f74476cE49ee197a1Af6E803ea.json new file mode 100644 index 0000000000..9a4ac80fa5 --- /dev/null +++ b/packages/core/deployments/amoy/Batch-0xC9bAbb4B452Dd9f74476cE49ee197a1Af6E803ea.json @@ -0,0 +1,420 @@ +{ + "address": "0x6db400c5523e9BB8fe1B517ef42278e97fF75ACA", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_executor", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Batch.Execution[]", + "name": "executions", + "type": "tuple[]" + } + ], + "name": "atomicBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct Batch.ExecutionWithETH[]", + "name": "executions", + "type": "tuple[]" + } + ], + "name": "atomicBatchWithETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "executor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Batch.Execution[]", + "name": "executions", + "type": "tuple[]" + } + ], + "name": "nonAtomicBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct Batch.ExecutionWithETH[]", + "name": "executions", + "type": "tuple[]" + } + ], + "name": "nonAtomicBatchWithETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes[]", + "name": "callDatas", + "type": "bytes[]" + } + ], + "name": "singleTargetAtomicBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct Batch.SingleTargetExecutionWithETH[]", + "name": "executions", + "type": "tuple[]" + } + ], + "name": "singleTargetAtomicBatchWithETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes[]", + "name": "callDatas", + "type": "bytes[]" + } + ], + "name": "singleTargetNonAtomicBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct Batch.SingleTargetExecutionWithETH[]", + "name": "executions", + "type": "tuple[]" + } + ], + "name": "singleTargetNonAtomicBatchWithETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0xf098a9deae7b9c68e8a4845a1b78114e622ff2916018ba15777651d5c6ffb7a9", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0x6db400c5523e9BB8fe1B517ef42278e97fF75ACA", + "transactionIndex": 2, + "gasUsed": "1207713", + "logsBloom": "0x00000000000000000200000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000200001200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000108000000000000000000000000000000000000000000000000000000000000020000000100000", + "blockHash": "0x9abc046caecf07f7232651bd9235d08ffc9d8c99f0a07b7789ecdf879e063732", + "transactionHash": "0xf098a9deae7b9c68e8a4845a1b78114e622ff2916018ba15777651d5c6ffb7a9", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 11274861, + "transactionHash": "0xf098a9deae7b9c68e8a4845a1b78114e622ff2916018ba15777651d5c6ffb7a9", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000d07dd60077d3a5628837ada6002ea8ac5e689795" + ], + "data": "0x000000000000000000000000000000000000000000000000008d977ba3ceb7a100000000000000000000000000000000000000000000000214b552f95030ea3d0000000000000000000000000000000000000000000000190708fa15c9a9dd8d0000000000000000000000000000000000000000000000021427bb7dac62329c000000000000000000000000000000000000000000000019079691916d78952e", + "logIndex": 5, + "blockHash": "0x9abc046caecf07f7232651bd9235d08ffc9d8c99f0a07b7789ecdf879e063732" + } + ], + "blockNumber": 11274861, + "cumulativeGasUsed": "1377794", + "status": 1, + "byzantium": true + }, + "args": [ + "0xC9bAbb4B452Dd9f74476cE49ee197a1Af6E803ea" + ], + "numDeployments": 1, + "solcInputHash": "8647b3c46fdd7d95d4038ddf2cc1e589", + "metadata": "{\"compiler\":{\"version\":\"0.8.2+commit.661d1103\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_executor\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Batch.Execution[]\",\"name\":\"executions\",\"type\":\"tuple[]\"}],\"name\":\"atomicBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"struct Batch.ExecutionWithETH[]\",\"name\":\"executions\",\"type\":\"tuple[]\"}],\"name\":\"atomicBatchWithETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"executor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Batch.Execution[]\",\"name\":\"executions\",\"type\":\"tuple[]\"}],\"name\":\"nonAtomicBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"struct Batch.ExecutionWithETH[]\",\"name\":\"executions\",\"type\":\"tuple[]\"}],\"name\":\"nonAtomicBatchWithETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes[]\",\"name\":\"callDatas\",\"type\":\"bytes[]\"}],\"name\":\"singleTargetAtomicBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"struct Batch.SingleTargetExecutionWithETH[]\",\"name\":\"executions\",\"type\":\"tuple[]\"}],\"name\":\"singleTargetAtomicBatchWithETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes[]\",\"name\":\"callDatas\",\"type\":\"bytes[]\"}],\"name\":\"singleTargetNonAtomicBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"struct Batch.SingleTargetExecutionWithETH[]\",\"name\":\"executions\",\"type\":\"tuple[]\"}],\"name\":\"singleTargetNonAtomicBatchWithETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/solc_0.8/Utils/Batch.sol\":\"Batch\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":2000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-0.8/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\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 function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 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 Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(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\\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\",\"keccak256\":\"0x51b758a8815ecc9596c66c37d56b1d33883a444631a3f916b9fe65cb863ef7c4\",\"license\":\"MIT\"},\"src/solc_0.8/Utils/Batch.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.2;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"@openzeppelin/contracts-0.8/utils/Address.sol\\\";\\n\\ncontract Batch {\\n using Address for address;\\n\\n struct Execution {\\n address target;\\n bytes callData;\\n }\\n\\n struct ExecutionWithETH {\\n address target;\\n bytes callData;\\n uint256 value;\\n }\\n\\n struct SingleTargetExecutionWithETH {\\n bytes callData;\\n uint256 value;\\n }\\n\\n address public immutable executor;\\n\\n constructor(address _executor) {\\n executor = _executor;\\n }\\n\\n modifier onlyExecutor() {\\n require(msg.sender == executor, \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n function atomicBatchWithETH(ExecutionWithETH[] calldata executions) external payable onlyExecutor {\\n for (uint256 i = 0; i < executions.length; i++) {\\n executions[i].target.functionCallWithValue(executions[i].callData, executions[i].value);\\n }\\n }\\n\\n function nonAtomicBatchWithETH(ExecutionWithETH[] calldata executions) external payable onlyExecutor {\\n for (uint256 i = 0; i < executions.length; i++) {\\n _call(executions[i].target, executions[i].callData, executions[i].value);\\n }\\n }\\n\\n function atomicBatch(Execution[] calldata executions) external onlyExecutor {\\n for (uint256 i = 0; i < executions.length; i++) {\\n executions[i].target.functionCall(executions[i].callData);\\n }\\n }\\n\\n function nonAtomicBatch(Execution[] calldata executions) external onlyExecutor {\\n for (uint256 i = 0; i < executions.length; i++) {\\n _call(executions[i].target, executions[i].callData, 0);\\n }\\n }\\n\\n function singleTargetAtomicBatchWithETH(address target, SingleTargetExecutionWithETH[] calldata executions)\\n external\\n payable\\n onlyExecutor\\n {\\n for (uint256 i = 0; i < executions.length; i++) {\\n target.functionCallWithValue(executions[i].callData, executions[i].value);\\n }\\n }\\n\\n function singleTargetNonAtomicBatchWithETH(address target, SingleTargetExecutionWithETH[] calldata executions)\\n external\\n payable\\n onlyExecutor\\n {\\n for (uint256 i = 0; i < executions.length; i++) {\\n _call(target, executions[i].callData, executions[i].value);\\n }\\n }\\n\\n function singleTargetAtomicBatch(address target, bytes[] calldata callDatas) external onlyExecutor {\\n for (uint256 i = 0; i < callDatas.length; i++) {\\n target.functionCall(callDatas[i]);\\n }\\n }\\n\\n function singleTargetNonAtomicBatch(address target, bytes[] calldata callDatas) external onlyExecutor {\\n for (uint256 i = 0; i < callDatas.length; i++) {\\n _call(target, callDatas[i], 0);\\n }\\n }\\n\\n function _call(\\n address target,\\n bytes calldata data,\\n uint256 value\\n ) internal returns (bool) {\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, ) = target.call{value: value}(data);\\n return success;\\n }\\n\\n // ----------------------------------------------------------------------------------------------------\\n // TOKEN RECEPTION\\n // ----------------------------------------------------------------------------------------------------\\n\\n // ERC1155\\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\\n\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes calldata\\n ) external pure returns (bytes4) {\\n return ERC1155_RECEIVED;\\n }\\n\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] calldata,\\n uint256[] calldata,\\n bytes calldata\\n ) external pure returns (bytes4) {\\n return ERC1155_BATCH_RECEIVED;\\n }\\n\\n // ERC721\\n\\n bytes4 private constant ERC721_IS_RECEIVER = 0x150b7a02;\\n bytes4 private constant ERC721_RECEIVED = 0x150b7a02;\\n\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external pure returns (bytes4) {\\n return ERC721_RECEIVED;\\n }\\n\\n // ERC165\\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\\n return _interfaceId == 0x01ffc9a7 || _interfaceId == ERC1155_IS_RECEIVER || _interfaceId == ERC721_IS_RECEIVER;\\n }\\n}\\n\",\"keccak256\":\"0x2162ccc1b2bc75556f5058092b311f7cdd3537e4d36f8530eff40775890271a5\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b506040516115bb3803806115bb83398101604081905261002f91610044565b60601b6001600160601b031916608052610072565b600060208284031215610055578081fd5b81516001600160a01b038116811461006b578182fd5b9392505050565b60805160601c6114f36100c86000396000818161025601528181610334015281816105750152818161063f01528181610741015281816108c801528181610a0c01528181610b0d0152610c5201526114f36000f3fe6080604052600436106100d15760003560e01c806393538f111161007f578063d2570b3b11610059578063d2570b3b14610290578063f23a6e61146102b0578063f28503e9146102f6578063fad5f5ed14610309576100d1565b806393538f11146101e9578063bc197c81146101fc578063c34c08e514610244576100d1565b8063150b7a02116100b0578063150b7a021461014d578063570187a0146101c35780638fc17957146101d6576100d1565b8062ebd9e5146100d657806301ffc9a7146100f85780630dc09f2f1461012d575b600080fd5b3480156100e257600080fd5b506100f66100f136600461125d565b610329565b005b34801561010457600080fd5b5061011861011336600461129d565b610483565b60405190151581526020015b60405180910390f35b34801561013957600080fd5b506100f661014836600461120c565b61056a565b34801561015957600080fd5b50610192610168366004611129565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610124565b6100f66101d136600461120c565b610634565b6100f66101e436600461125d565b610736565b6100f66101f736600461120c565b6108bd565b34801561020857600080fd5b50610192610217366004611072565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b34801561025057600080fd5b506102787f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610124565b34801561029c57600080fd5b506100f66102ab36600461120c565b610a01565b3480156102bc57600080fd5b506101926102cb366004611196565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b6100f661030436600461125d565b610b02565b34801561031557600080fd5b506100f661032436600461125d565b610c47565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146103975760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60005b8181101561047e5761046b8383838181106103c557634e487b7160e01b600052603260045260246000fd5b90506020028101906103d791906113f0565b6103e590602081019061135a565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525087925086915085905081811061043c57634e487b7160e01b600052603260045260246000fd5b905060200281019061044e91906113f0565b61045c906020810190611058565b6001600160a01b031690610d51565b50806104768161144f565b91505061039a565b505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061051657507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061056257507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b90505b919050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105d35760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561062e5761061b8484848481811061060257634e487b7160e01b600052603260045260246000fd5b9050602002810190610614919061135a565b6000610d9a565b50806106268161144f565b9150506105d6565b50505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461069d5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561062e57610723848484848181106106cc57634e487b7160e01b600052603260045260246000fd5b90506020028101906106de91906113f0565b6106e8908061135a565b86868681811061070857634e487b7160e01b600052603260045260246000fd5b905060200281019061071a91906113f0565b60200135610d9a565b508061072e8161144f565b9150506106a0565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461079f5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561047e576108aa8383838181106107cd57634e487b7160e01b600052603260045260246000fd5b90506020028101906107df91906113bd565b6107ed90602081019061135a565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525087925086915085905081811061084457634e487b7160e01b600052603260045260246000fd5b905060200281019061085691906113bd565b6040013585858581811061087a57634e487b7160e01b600052603260045260246000fd5b905060200281019061088c91906113bd565b61089a906020810190611058565b6001600160a01b03169190610e07565b50806108b58161144f565b9150506107a2565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146109265760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561062e576109ee83838381811061095457634e487b7160e01b600052603260045260246000fd5b905060200281019061096691906113f0565b610970908061135a565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508792508691508590508181106109c757634e487b7160e01b600052603260045260246000fd5b90506020028101906109d991906113f0565b6001600160a01b038716919060200135610e07565b50806109f98161144f565b915050610929565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610a6a5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561062e57610aef838383818110610a9857634e487b7160e01b600052603260045260246000fd5b9050602002810190610aaa919061135a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506001600160a01b03881692915050610d51565b5080610afa8161144f565b915050610a6d565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b6b5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561047e57610c34838383818110610b9957634e487b7160e01b600052603260045260246000fd5b9050602002810190610bab91906113bd565b610bb9906020810190611058565b848484818110610bd957634e487b7160e01b600052603260045260246000fd5b9050602002810190610beb91906113bd565b610bf990602081019061135a565b868686818110610c1957634e487b7160e01b600052603260045260246000fd5b9050602002810190610c2b91906113bd565b60400135610d9a565b5080610c3f8161144f565b915050610b6e565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610cb05760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561047e57610d3e838383818110610cde57634e487b7160e01b600052603260045260246000fd5b9050602002810190610cf091906113f0565b610cfe906020810190611058565b848484818110610d1e57634e487b7160e01b600052603260045260246000fd5b9050602002810190610d3091906113f0565b61061490602081019061135a565b5080610d498161144f565b915050610cb3565b6060610d9383836040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c65640000815250610e35565b9392505050565b600080856001600160a01b0316838686604051610db89291906112dd565b60006040518083038185875af1925050503d8060008114610df5576040519150601f19603f3d011682016040523d82523d6000602084013e610dfa565b606091505b5090979650505050505050565b6060610e2d84848460405180606001604052806029815260200161149560299139610e40565b949350505050565b6060610e2d84846000855b606082471015610eb85760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161038e565b843b610f065760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161038e565b600080866001600160a01b03168587604051610f2291906112ed565b60006040518083038185875af1925050503d8060008114610f5f576040519150601f19603f3d011682016040523d82523d6000602084013e610f64565b606091505b5091509150610f74828286610f7f565b979650505050505050565b60608315610f8e575081610d93565b825115610f9e5782518084602001fd5b8160405162461bcd60e51b815260040161038e9190611309565b80356001600160a01b038116811461056557600080fd5b60008083601f840112610fe0578182fd5b50813567ffffffffffffffff811115610ff7578182fd5b602083019150836020808302850101111561101157600080fd5b9250929050565b60008083601f840112611029578182fd5b50813567ffffffffffffffff811115611040578182fd5b60208301915083602082850101111561101157600080fd5b600060208284031215611069578081fd5b610d9382610fb8565b60008060008060008060008060a0898b03121561108d578384fd5b61109689610fb8565b97506110a460208a01610fb8565b9650604089013567ffffffffffffffff808211156110c0578586fd5b6110cc8c838d01610fcf565b909850965060608b01359150808211156110e4578586fd5b6110f08c838d01610fcf565b909650945060808b0135915080821115611108578384fd5b506111158b828c01611018565b999c989b5096995094979396929594505050565b600080600080600060808688031215611140578081fd5b61114986610fb8565b945061115760208701610fb8565b935060408601359250606086013567ffffffffffffffff811115611179578182fd5b61118588828901611018565b969995985093965092949392505050565b60008060008060008060a087890312156111ae578182fd5b6111b787610fb8565b95506111c560208801610fb8565b94506040870135935060608701359250608087013567ffffffffffffffff8111156111ee578283fd5b6111fa89828a01611018565b979a9699509497509295939492505050565b600080600060408486031215611220578283fd5b61122984610fb8565b9250602084013567ffffffffffffffff811115611244578283fd5b61125086828701610fcf565b9497909650939450505050565b6000806020838503121561126f578182fd5b823567ffffffffffffffff811115611285578283fd5b61129185828601610fcf565b90969095509350505050565b6000602082840312156112ae578081fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610d93578182fd5b6000828483379101908152919050565b600082516112ff818460208701611423565b9190910192915050565b6000602082528251806020840152611328816040850160208701611423565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261138e578283fd5b83018035915067ffffffffffffffff8211156113a8578283fd5b60200191503681900382131561101157600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18336030181126112ff578182fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126112ff578182fd5b60005b8381101561143e578181015183820152602001611426565b8381111561062e5750506000910152565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561148d57634e487b7160e01b81526011600452602481fd5b506001019056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a2646970667358221220f7c425c3a3feed3f4634aa8703a8b0eb3a605b60d3041f062774fa50ba15f46364736f6c63430008020033", + "deployedBytecode": "0x6080604052600436106100d15760003560e01c806393538f111161007f578063d2570b3b11610059578063d2570b3b14610290578063f23a6e61146102b0578063f28503e9146102f6578063fad5f5ed14610309576100d1565b806393538f11146101e9578063bc197c81146101fc578063c34c08e514610244576100d1565b8063150b7a02116100b0578063150b7a021461014d578063570187a0146101c35780638fc17957146101d6576100d1565b8062ebd9e5146100d657806301ffc9a7146100f85780630dc09f2f1461012d575b600080fd5b3480156100e257600080fd5b506100f66100f136600461125d565b610329565b005b34801561010457600080fd5b5061011861011336600461129d565b610483565b60405190151581526020015b60405180910390f35b34801561013957600080fd5b506100f661014836600461120c565b61056a565b34801561015957600080fd5b50610192610168366004611129565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610124565b6100f66101d136600461120c565b610634565b6100f66101e436600461125d565b610736565b6100f66101f736600461120c565b6108bd565b34801561020857600080fd5b50610192610217366004611072565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b34801561025057600080fd5b506102787f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610124565b34801561029c57600080fd5b506100f66102ab36600461120c565b610a01565b3480156102bc57600080fd5b506101926102cb366004611196565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b6100f661030436600461125d565b610b02565b34801561031557600080fd5b506100f661032436600461125d565b610c47565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146103975760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60005b8181101561047e5761046b8383838181106103c557634e487b7160e01b600052603260045260246000fd5b90506020028101906103d791906113f0565b6103e590602081019061135a565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525087925086915085905081811061043c57634e487b7160e01b600052603260045260246000fd5b905060200281019061044e91906113f0565b61045c906020810190611058565b6001600160a01b031690610d51565b50806104768161144f565b91505061039a565b505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061051657507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061056257507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b90505b919050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105d35760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561062e5761061b8484848481811061060257634e487b7160e01b600052603260045260246000fd5b9050602002810190610614919061135a565b6000610d9a565b50806106268161144f565b9150506105d6565b50505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461069d5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561062e57610723848484848181106106cc57634e487b7160e01b600052603260045260246000fd5b90506020028101906106de91906113f0565b6106e8908061135a565b86868681811061070857634e487b7160e01b600052603260045260246000fd5b905060200281019061071a91906113f0565b60200135610d9a565b508061072e8161144f565b9150506106a0565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461079f5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561047e576108aa8383838181106107cd57634e487b7160e01b600052603260045260246000fd5b90506020028101906107df91906113bd565b6107ed90602081019061135a565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525087925086915085905081811061084457634e487b7160e01b600052603260045260246000fd5b905060200281019061085691906113bd565b6040013585858581811061087a57634e487b7160e01b600052603260045260246000fd5b905060200281019061088c91906113bd565b61089a906020810190611058565b6001600160a01b03169190610e07565b50806108b58161144f565b9150506107a2565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146109265760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561062e576109ee83838381811061095457634e487b7160e01b600052603260045260246000fd5b905060200281019061096691906113f0565b610970908061135a565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508792508691508590508181106109c757634e487b7160e01b600052603260045260246000fd5b90506020028101906109d991906113f0565b6001600160a01b038716919060200135610e07565b50806109f98161144f565b915050610929565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610a6a5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561062e57610aef838383818110610a9857634e487b7160e01b600052603260045260246000fd5b9050602002810190610aaa919061135a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506001600160a01b03881692915050610d51565b5080610afa8161144f565b915050610a6d565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b6b5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561047e57610c34838383818110610b9957634e487b7160e01b600052603260045260246000fd5b9050602002810190610bab91906113bd565b610bb9906020810190611058565b848484818110610bd957634e487b7160e01b600052603260045260246000fd5b9050602002810190610beb91906113bd565b610bf990602081019061135a565b868686818110610c1957634e487b7160e01b600052603260045260246000fd5b9050602002810190610c2b91906113bd565b60400135610d9a565b5080610c3f8161144f565b915050610b6e565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610cb05760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561047e57610d3e838383818110610cde57634e487b7160e01b600052603260045260246000fd5b9050602002810190610cf091906113f0565b610cfe906020810190611058565b848484818110610d1e57634e487b7160e01b600052603260045260246000fd5b9050602002810190610d3091906113f0565b61061490602081019061135a565b5080610d498161144f565b915050610cb3565b6060610d9383836040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c65640000815250610e35565b9392505050565b600080856001600160a01b0316838686604051610db89291906112dd565b60006040518083038185875af1925050503d8060008114610df5576040519150601f19603f3d011682016040523d82523d6000602084013e610dfa565b606091505b5090979650505050505050565b6060610e2d84848460405180606001604052806029815260200161149560299139610e40565b949350505050565b6060610e2d84846000855b606082471015610eb85760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161038e565b843b610f065760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161038e565b600080866001600160a01b03168587604051610f2291906112ed565b60006040518083038185875af1925050503d8060008114610f5f576040519150601f19603f3d011682016040523d82523d6000602084013e610f64565b606091505b5091509150610f74828286610f7f565b979650505050505050565b60608315610f8e575081610d93565b825115610f9e5782518084602001fd5b8160405162461bcd60e51b815260040161038e9190611309565b80356001600160a01b038116811461056557600080fd5b60008083601f840112610fe0578182fd5b50813567ffffffffffffffff811115610ff7578182fd5b602083019150836020808302850101111561101157600080fd5b9250929050565b60008083601f840112611029578182fd5b50813567ffffffffffffffff811115611040578182fd5b60208301915083602082850101111561101157600080fd5b600060208284031215611069578081fd5b610d9382610fb8565b60008060008060008060008060a0898b03121561108d578384fd5b61109689610fb8565b97506110a460208a01610fb8565b9650604089013567ffffffffffffffff808211156110c0578586fd5b6110cc8c838d01610fcf565b909850965060608b01359150808211156110e4578586fd5b6110f08c838d01610fcf565b909650945060808b0135915080821115611108578384fd5b506111158b828c01611018565b999c989b5096995094979396929594505050565b600080600080600060808688031215611140578081fd5b61114986610fb8565b945061115760208701610fb8565b935060408601359250606086013567ffffffffffffffff811115611179578182fd5b61118588828901611018565b969995985093965092949392505050565b60008060008060008060a087890312156111ae578182fd5b6111b787610fb8565b95506111c560208801610fb8565b94506040870135935060608701359250608087013567ffffffffffffffff8111156111ee578283fd5b6111fa89828a01611018565b979a9699509497509295939492505050565b600080600060408486031215611220578283fd5b61122984610fb8565b9250602084013567ffffffffffffffff811115611244578283fd5b61125086828701610fcf565b9497909650939450505050565b6000806020838503121561126f578182fd5b823567ffffffffffffffff811115611285578283fd5b61129185828601610fcf565b90969095509350505050565b6000602082840312156112ae578081fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610d93578182fd5b6000828483379101908152919050565b600082516112ff818460208701611423565b9190910192915050565b6000602082528251806020840152611328816040850160208701611423565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261138e578283fd5b83018035915067ffffffffffffffff8211156113a8578283fd5b60200191503681900382131561101157600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18336030181126112ff578182fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126112ff578182fd5b60005b8381101561143e578181015183820152602001611426565b8381111561062e5750506000910152565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561148d57634e487b7160e01b81526011600452602481fd5b506001019056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a2646970667358221220f7c425c3a3feed3f4634aa8703a8b0eb3a605b60d3041f062774fa50ba15f46364736f6c63430008020033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/packages/core/deployments/polygon/Batch-0x7A9fe22691c811ea339D9B73150e6911a5343DcA.json b/packages/core/deployments/polygon/Batch-0x7A9fe22691c811ea339D9B73150e6911a5343DcA.json new file mode 100644 index 0000000000..03d1a2954e --- /dev/null +++ b/packages/core/deployments/polygon/Batch-0x7A9fe22691c811ea339D9B73150e6911a5343DcA.json @@ -0,0 +1,420 @@ +{ + "address": "0xB8E6432b1573b28E2d33E63Bcdac93e030f3A630", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_executor", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Batch.Execution[]", + "name": "executions", + "type": "tuple[]" + } + ], + "name": "atomicBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct Batch.ExecutionWithETH[]", + "name": "executions", + "type": "tuple[]" + } + ], + "name": "atomicBatchWithETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "executor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Batch.Execution[]", + "name": "executions", + "type": "tuple[]" + } + ], + "name": "nonAtomicBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct Batch.ExecutionWithETH[]", + "name": "executions", + "type": "tuple[]" + } + ], + "name": "nonAtomicBatchWithETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes[]", + "name": "callDatas", + "type": "bytes[]" + } + ], + "name": "singleTargetAtomicBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct Batch.SingleTargetExecutionWithETH[]", + "name": "executions", + "type": "tuple[]" + } + ], + "name": "singleTargetAtomicBatchWithETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes[]", + "name": "callDatas", + "type": "bytes[]" + } + ], + "name": "singleTargetNonAtomicBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct Batch.SingleTargetExecutionWithETH[]", + "name": "executions", + "type": "tuple[]" + } + ], + "name": "singleTargetNonAtomicBatchWithETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x59cf4c0295aba34344c1834023df8788807575eab2200c8a6a72a62abcfe44d3", + "receipt": { + "to": null, + "from": "0x114B1d9f0d546B8f85C4003dcd4ca5CbB7F6bC98", + "contractAddress": "0xB8E6432b1573b28E2d33E63Bcdac93e030f3A630", + "transactionIndex": 39, + "gasUsed": "1207713", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000400000000100000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000800000000000000000000100000000000000000000080000000000000000000004000000000000000000000000000100000", + "blockHash": "0x9ff250ff1d56042accd518939199e23fdcc51bb3c2d022bb2f45f281c2bc9805", + "transactionHash": "0x59cf4c0295aba34344c1834023df8788807575eab2200c8a6a72a62abcfe44d3", + "logs": [ + { + "transactionIndex": 39, + "blockNumber": 61145509, + "transactionHash": "0x59cf4c0295aba34344c1834023df8788807575eab2200c8a6a72a62abcfe44d3", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000114b1d9f0d546b8f85c4003dcd4ca5cbb7f6bc98", + "0x0000000000000000000000007c7379531b2aee82e4ca06d4175d13b9cbeafd49" + ], + "data": "0x00000000000000000000000000000000000000000000000000da6223992160480000000000000000000000000000000000000000000000004da580deec5b38870000000000000000000000000000000000000000000327131c9bef04661ff2a20000000000000000000000000000000000000000000000004ccb1ebb5339d83f0000000000000000000000000000000000000000000327131d765127ff4152ea", + "logIndex": 194, + "blockHash": "0x9ff250ff1d56042accd518939199e23fdcc51bb3c2d022bb2f45f281c2bc9805" + } + ], + "blockNumber": 61145509, + "cumulativeGasUsed": "7019839", + "status": 1, + "byzantium": true + }, + "args": [ + "0x7A9fe22691c811ea339D9B73150e6911a5343DcA" + ], + "numDeployments": 1, + "solcInputHash": "8647b3c46fdd7d95d4038ddf2cc1e589", + "metadata": "{\"compiler\":{\"version\":\"0.8.2+commit.661d1103\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_executor\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Batch.Execution[]\",\"name\":\"executions\",\"type\":\"tuple[]\"}],\"name\":\"atomicBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"struct Batch.ExecutionWithETH[]\",\"name\":\"executions\",\"type\":\"tuple[]\"}],\"name\":\"atomicBatchWithETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"executor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Batch.Execution[]\",\"name\":\"executions\",\"type\":\"tuple[]\"}],\"name\":\"nonAtomicBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"struct Batch.ExecutionWithETH[]\",\"name\":\"executions\",\"type\":\"tuple[]\"}],\"name\":\"nonAtomicBatchWithETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes[]\",\"name\":\"callDatas\",\"type\":\"bytes[]\"}],\"name\":\"singleTargetAtomicBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"struct Batch.SingleTargetExecutionWithETH[]\",\"name\":\"executions\",\"type\":\"tuple[]\"}],\"name\":\"singleTargetAtomicBatchWithETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes[]\",\"name\":\"callDatas\",\"type\":\"bytes[]\"}],\"name\":\"singleTargetNonAtomicBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"struct Batch.SingleTargetExecutionWithETH[]\",\"name\":\"executions\",\"type\":\"tuple[]\"}],\"name\":\"singleTargetNonAtomicBatchWithETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/solc_0.8/Utils/Batch.sol\":\"Batch\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":2000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-0.8/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\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 function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 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 Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(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\\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\",\"keccak256\":\"0x51b758a8815ecc9596c66c37d56b1d33883a444631a3f916b9fe65cb863ef7c4\",\"license\":\"MIT\"},\"src/solc_0.8/Utils/Batch.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.2;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"@openzeppelin/contracts-0.8/utils/Address.sol\\\";\\n\\ncontract Batch {\\n using Address for address;\\n\\n struct Execution {\\n address target;\\n bytes callData;\\n }\\n\\n struct ExecutionWithETH {\\n address target;\\n bytes callData;\\n uint256 value;\\n }\\n\\n struct SingleTargetExecutionWithETH {\\n bytes callData;\\n uint256 value;\\n }\\n\\n address public immutable executor;\\n\\n constructor(address _executor) {\\n executor = _executor;\\n }\\n\\n modifier onlyExecutor() {\\n require(msg.sender == executor, \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n function atomicBatchWithETH(ExecutionWithETH[] calldata executions) external payable onlyExecutor {\\n for (uint256 i = 0; i < executions.length; i++) {\\n executions[i].target.functionCallWithValue(executions[i].callData, executions[i].value);\\n }\\n }\\n\\n function nonAtomicBatchWithETH(ExecutionWithETH[] calldata executions) external payable onlyExecutor {\\n for (uint256 i = 0; i < executions.length; i++) {\\n _call(executions[i].target, executions[i].callData, executions[i].value);\\n }\\n }\\n\\n function atomicBatch(Execution[] calldata executions) external onlyExecutor {\\n for (uint256 i = 0; i < executions.length; i++) {\\n executions[i].target.functionCall(executions[i].callData);\\n }\\n }\\n\\n function nonAtomicBatch(Execution[] calldata executions) external onlyExecutor {\\n for (uint256 i = 0; i < executions.length; i++) {\\n _call(executions[i].target, executions[i].callData, 0);\\n }\\n }\\n\\n function singleTargetAtomicBatchWithETH(address target, SingleTargetExecutionWithETH[] calldata executions)\\n external\\n payable\\n onlyExecutor\\n {\\n for (uint256 i = 0; i < executions.length; i++) {\\n target.functionCallWithValue(executions[i].callData, executions[i].value);\\n }\\n }\\n\\n function singleTargetNonAtomicBatchWithETH(address target, SingleTargetExecutionWithETH[] calldata executions)\\n external\\n payable\\n onlyExecutor\\n {\\n for (uint256 i = 0; i < executions.length; i++) {\\n _call(target, executions[i].callData, executions[i].value);\\n }\\n }\\n\\n function singleTargetAtomicBatch(address target, bytes[] calldata callDatas) external onlyExecutor {\\n for (uint256 i = 0; i < callDatas.length; i++) {\\n target.functionCall(callDatas[i]);\\n }\\n }\\n\\n function singleTargetNonAtomicBatch(address target, bytes[] calldata callDatas) external onlyExecutor {\\n for (uint256 i = 0; i < callDatas.length; i++) {\\n _call(target, callDatas[i], 0);\\n }\\n }\\n\\n function _call(\\n address target,\\n bytes calldata data,\\n uint256 value\\n ) internal returns (bool) {\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, ) = target.call{value: value}(data);\\n return success;\\n }\\n\\n // ----------------------------------------------------------------------------------------------------\\n // TOKEN RECEPTION\\n // ----------------------------------------------------------------------------------------------------\\n\\n // ERC1155\\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\\n\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes calldata\\n ) external pure returns (bytes4) {\\n return ERC1155_RECEIVED;\\n }\\n\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] calldata,\\n uint256[] calldata,\\n bytes calldata\\n ) external pure returns (bytes4) {\\n return ERC1155_BATCH_RECEIVED;\\n }\\n\\n // ERC721\\n\\n bytes4 private constant ERC721_IS_RECEIVER = 0x150b7a02;\\n bytes4 private constant ERC721_RECEIVED = 0x150b7a02;\\n\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external pure returns (bytes4) {\\n return ERC721_RECEIVED;\\n }\\n\\n // ERC165\\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\\n return _interfaceId == 0x01ffc9a7 || _interfaceId == ERC1155_IS_RECEIVER || _interfaceId == ERC721_IS_RECEIVER;\\n }\\n}\\n\",\"keccak256\":\"0x2162ccc1b2bc75556f5058092b311f7cdd3537e4d36f8530eff40775890271a5\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b506040516115bb3803806115bb83398101604081905261002f91610044565b60601b6001600160601b031916608052610072565b600060208284031215610055578081fd5b81516001600160a01b038116811461006b578182fd5b9392505050565b60805160601c6114f36100c86000396000818161025601528181610334015281816105750152818161063f01528181610741015281816108c801528181610a0c01528181610b0d0152610c5201526114f36000f3fe6080604052600436106100d15760003560e01c806393538f111161007f578063d2570b3b11610059578063d2570b3b14610290578063f23a6e61146102b0578063f28503e9146102f6578063fad5f5ed14610309576100d1565b806393538f11146101e9578063bc197c81146101fc578063c34c08e514610244576100d1565b8063150b7a02116100b0578063150b7a021461014d578063570187a0146101c35780638fc17957146101d6576100d1565b8062ebd9e5146100d657806301ffc9a7146100f85780630dc09f2f1461012d575b600080fd5b3480156100e257600080fd5b506100f66100f136600461125d565b610329565b005b34801561010457600080fd5b5061011861011336600461129d565b610483565b60405190151581526020015b60405180910390f35b34801561013957600080fd5b506100f661014836600461120c565b61056a565b34801561015957600080fd5b50610192610168366004611129565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610124565b6100f66101d136600461120c565b610634565b6100f66101e436600461125d565b610736565b6100f66101f736600461120c565b6108bd565b34801561020857600080fd5b50610192610217366004611072565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b34801561025057600080fd5b506102787f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610124565b34801561029c57600080fd5b506100f66102ab36600461120c565b610a01565b3480156102bc57600080fd5b506101926102cb366004611196565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b6100f661030436600461125d565b610b02565b34801561031557600080fd5b506100f661032436600461125d565b610c47565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146103975760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60005b8181101561047e5761046b8383838181106103c557634e487b7160e01b600052603260045260246000fd5b90506020028101906103d791906113f0565b6103e590602081019061135a565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525087925086915085905081811061043c57634e487b7160e01b600052603260045260246000fd5b905060200281019061044e91906113f0565b61045c906020810190611058565b6001600160a01b031690610d51565b50806104768161144f565b91505061039a565b505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061051657507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061056257507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b90505b919050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105d35760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561062e5761061b8484848481811061060257634e487b7160e01b600052603260045260246000fd5b9050602002810190610614919061135a565b6000610d9a565b50806106268161144f565b9150506105d6565b50505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461069d5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561062e57610723848484848181106106cc57634e487b7160e01b600052603260045260246000fd5b90506020028101906106de91906113f0565b6106e8908061135a565b86868681811061070857634e487b7160e01b600052603260045260246000fd5b905060200281019061071a91906113f0565b60200135610d9a565b508061072e8161144f565b9150506106a0565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461079f5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561047e576108aa8383838181106107cd57634e487b7160e01b600052603260045260246000fd5b90506020028101906107df91906113bd565b6107ed90602081019061135a565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525087925086915085905081811061084457634e487b7160e01b600052603260045260246000fd5b905060200281019061085691906113bd565b6040013585858581811061087a57634e487b7160e01b600052603260045260246000fd5b905060200281019061088c91906113bd565b61089a906020810190611058565b6001600160a01b03169190610e07565b50806108b58161144f565b9150506107a2565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146109265760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561062e576109ee83838381811061095457634e487b7160e01b600052603260045260246000fd5b905060200281019061096691906113f0565b610970908061135a565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508792508691508590508181106109c757634e487b7160e01b600052603260045260246000fd5b90506020028101906109d991906113f0565b6001600160a01b038716919060200135610e07565b50806109f98161144f565b915050610929565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610a6a5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561062e57610aef838383818110610a9857634e487b7160e01b600052603260045260246000fd5b9050602002810190610aaa919061135a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506001600160a01b03881692915050610d51565b5080610afa8161144f565b915050610a6d565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b6b5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561047e57610c34838383818110610b9957634e487b7160e01b600052603260045260246000fd5b9050602002810190610bab91906113bd565b610bb9906020810190611058565b848484818110610bd957634e487b7160e01b600052603260045260246000fd5b9050602002810190610beb91906113bd565b610bf990602081019061135a565b868686818110610c1957634e487b7160e01b600052603260045260246000fd5b9050602002810190610c2b91906113bd565b60400135610d9a565b5080610c3f8161144f565b915050610b6e565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610cb05760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561047e57610d3e838383818110610cde57634e487b7160e01b600052603260045260246000fd5b9050602002810190610cf091906113f0565b610cfe906020810190611058565b848484818110610d1e57634e487b7160e01b600052603260045260246000fd5b9050602002810190610d3091906113f0565b61061490602081019061135a565b5080610d498161144f565b915050610cb3565b6060610d9383836040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c65640000815250610e35565b9392505050565b600080856001600160a01b0316838686604051610db89291906112dd565b60006040518083038185875af1925050503d8060008114610df5576040519150601f19603f3d011682016040523d82523d6000602084013e610dfa565b606091505b5090979650505050505050565b6060610e2d84848460405180606001604052806029815260200161149560299139610e40565b949350505050565b6060610e2d84846000855b606082471015610eb85760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161038e565b843b610f065760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161038e565b600080866001600160a01b03168587604051610f2291906112ed565b60006040518083038185875af1925050503d8060008114610f5f576040519150601f19603f3d011682016040523d82523d6000602084013e610f64565b606091505b5091509150610f74828286610f7f565b979650505050505050565b60608315610f8e575081610d93565b825115610f9e5782518084602001fd5b8160405162461bcd60e51b815260040161038e9190611309565b80356001600160a01b038116811461056557600080fd5b60008083601f840112610fe0578182fd5b50813567ffffffffffffffff811115610ff7578182fd5b602083019150836020808302850101111561101157600080fd5b9250929050565b60008083601f840112611029578182fd5b50813567ffffffffffffffff811115611040578182fd5b60208301915083602082850101111561101157600080fd5b600060208284031215611069578081fd5b610d9382610fb8565b60008060008060008060008060a0898b03121561108d578384fd5b61109689610fb8565b97506110a460208a01610fb8565b9650604089013567ffffffffffffffff808211156110c0578586fd5b6110cc8c838d01610fcf565b909850965060608b01359150808211156110e4578586fd5b6110f08c838d01610fcf565b909650945060808b0135915080821115611108578384fd5b506111158b828c01611018565b999c989b5096995094979396929594505050565b600080600080600060808688031215611140578081fd5b61114986610fb8565b945061115760208701610fb8565b935060408601359250606086013567ffffffffffffffff811115611179578182fd5b61118588828901611018565b969995985093965092949392505050565b60008060008060008060a087890312156111ae578182fd5b6111b787610fb8565b95506111c560208801610fb8565b94506040870135935060608701359250608087013567ffffffffffffffff8111156111ee578283fd5b6111fa89828a01611018565b979a9699509497509295939492505050565b600080600060408486031215611220578283fd5b61122984610fb8565b9250602084013567ffffffffffffffff811115611244578283fd5b61125086828701610fcf565b9497909650939450505050565b6000806020838503121561126f578182fd5b823567ffffffffffffffff811115611285578283fd5b61129185828601610fcf565b90969095509350505050565b6000602082840312156112ae578081fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610d93578182fd5b6000828483379101908152919050565b600082516112ff818460208701611423565b9190910192915050565b6000602082528251806020840152611328816040850160208701611423565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261138e578283fd5b83018035915067ffffffffffffffff8211156113a8578283fd5b60200191503681900382131561101157600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18336030181126112ff578182fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126112ff578182fd5b60005b8381101561143e578181015183820152602001611426565b8381111561062e5750506000910152565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561148d57634e487b7160e01b81526011600452602481fd5b506001019056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a2646970667358221220f7c425c3a3feed3f4634aa8703a8b0eb3a605b60d3041f062774fa50ba15f46364736f6c63430008020033", + "deployedBytecode": "0x6080604052600436106100d15760003560e01c806393538f111161007f578063d2570b3b11610059578063d2570b3b14610290578063f23a6e61146102b0578063f28503e9146102f6578063fad5f5ed14610309576100d1565b806393538f11146101e9578063bc197c81146101fc578063c34c08e514610244576100d1565b8063150b7a02116100b0578063150b7a021461014d578063570187a0146101c35780638fc17957146101d6576100d1565b8062ebd9e5146100d657806301ffc9a7146100f85780630dc09f2f1461012d575b600080fd5b3480156100e257600080fd5b506100f66100f136600461125d565b610329565b005b34801561010457600080fd5b5061011861011336600461129d565b610483565b60405190151581526020015b60405180910390f35b34801561013957600080fd5b506100f661014836600461120c565b61056a565b34801561015957600080fd5b50610192610168366004611129565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610124565b6100f66101d136600461120c565b610634565b6100f66101e436600461125d565b610736565b6100f66101f736600461120c565b6108bd565b34801561020857600080fd5b50610192610217366004611072565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b34801561025057600080fd5b506102787f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610124565b34801561029c57600080fd5b506100f66102ab36600461120c565b610a01565b3480156102bc57600080fd5b506101926102cb366004611196565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b6100f661030436600461125d565b610b02565b34801561031557600080fd5b506100f661032436600461125d565b610c47565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146103975760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60005b8181101561047e5761046b8383838181106103c557634e487b7160e01b600052603260045260246000fd5b90506020028101906103d791906113f0565b6103e590602081019061135a565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525087925086915085905081811061043c57634e487b7160e01b600052603260045260246000fd5b905060200281019061044e91906113f0565b61045c906020810190611058565b6001600160a01b031690610d51565b50806104768161144f565b91505061039a565b505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061051657507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061056257507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b90505b919050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105d35760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561062e5761061b8484848481811061060257634e487b7160e01b600052603260045260246000fd5b9050602002810190610614919061135a565b6000610d9a565b50806106268161144f565b9150506105d6565b50505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461069d5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561062e57610723848484848181106106cc57634e487b7160e01b600052603260045260246000fd5b90506020028101906106de91906113f0565b6106e8908061135a565b86868681811061070857634e487b7160e01b600052603260045260246000fd5b905060200281019061071a91906113f0565b60200135610d9a565b508061072e8161144f565b9150506106a0565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461079f5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561047e576108aa8383838181106107cd57634e487b7160e01b600052603260045260246000fd5b90506020028101906107df91906113bd565b6107ed90602081019061135a565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525087925086915085905081811061084457634e487b7160e01b600052603260045260246000fd5b905060200281019061085691906113bd565b6040013585858581811061087a57634e487b7160e01b600052603260045260246000fd5b905060200281019061088c91906113bd565b61089a906020810190611058565b6001600160a01b03169190610e07565b50806108b58161144f565b9150506107a2565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146109265760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561062e576109ee83838381811061095457634e487b7160e01b600052603260045260246000fd5b905060200281019061096691906113f0565b610970908061135a565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508792508691508590508181106109c757634e487b7160e01b600052603260045260246000fd5b90506020028101906109d991906113f0565b6001600160a01b038716919060200135610e07565b50806109f98161144f565b915050610929565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610a6a5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561062e57610aef838383818110610a9857634e487b7160e01b600052603260045260246000fd5b9050602002810190610aaa919061135a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506001600160a01b03881692915050610d51565b5080610afa8161144f565b915050610a6d565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b6b5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561047e57610c34838383818110610b9957634e487b7160e01b600052603260045260246000fd5b9050602002810190610bab91906113bd565b610bb9906020810190611058565b848484818110610bd957634e487b7160e01b600052603260045260246000fd5b9050602002810190610beb91906113bd565b610bf990602081019061135a565b868686818110610c1957634e487b7160e01b600052603260045260246000fd5b9050602002810190610c2b91906113bd565b60400135610d9a565b5080610c3f8161144f565b915050610b6e565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610cb05760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161038e565b60005b8181101561047e57610d3e838383818110610cde57634e487b7160e01b600052603260045260246000fd5b9050602002810190610cf091906113f0565b610cfe906020810190611058565b848484818110610d1e57634e487b7160e01b600052603260045260246000fd5b9050602002810190610d3091906113f0565b61061490602081019061135a565b5080610d498161144f565b915050610cb3565b6060610d9383836040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c65640000815250610e35565b9392505050565b600080856001600160a01b0316838686604051610db89291906112dd565b60006040518083038185875af1925050503d8060008114610df5576040519150601f19603f3d011682016040523d82523d6000602084013e610dfa565b606091505b5090979650505050505050565b6060610e2d84848460405180606001604052806029815260200161149560299139610e40565b949350505050565b6060610e2d84846000855b606082471015610eb85760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161038e565b843b610f065760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161038e565b600080866001600160a01b03168587604051610f2291906112ed565b60006040518083038185875af1925050503d8060008114610f5f576040519150601f19603f3d011682016040523d82523d6000602084013e610f64565b606091505b5091509150610f74828286610f7f565b979650505050505050565b60608315610f8e575081610d93565b825115610f9e5782518084602001fd5b8160405162461bcd60e51b815260040161038e9190611309565b80356001600160a01b038116811461056557600080fd5b60008083601f840112610fe0578182fd5b50813567ffffffffffffffff811115610ff7578182fd5b602083019150836020808302850101111561101157600080fd5b9250929050565b60008083601f840112611029578182fd5b50813567ffffffffffffffff811115611040578182fd5b60208301915083602082850101111561101157600080fd5b600060208284031215611069578081fd5b610d9382610fb8565b60008060008060008060008060a0898b03121561108d578384fd5b61109689610fb8565b97506110a460208a01610fb8565b9650604089013567ffffffffffffffff808211156110c0578586fd5b6110cc8c838d01610fcf565b909850965060608b01359150808211156110e4578586fd5b6110f08c838d01610fcf565b909650945060808b0135915080821115611108578384fd5b506111158b828c01611018565b999c989b5096995094979396929594505050565b600080600080600060808688031215611140578081fd5b61114986610fb8565b945061115760208701610fb8565b935060408601359250606086013567ffffffffffffffff811115611179578182fd5b61118588828901611018565b969995985093965092949392505050565b60008060008060008060a087890312156111ae578182fd5b6111b787610fb8565b95506111c560208801610fb8565b94506040870135935060608701359250608087013567ffffffffffffffff8111156111ee578283fd5b6111fa89828a01611018565b979a9699509497509295939492505050565b600080600060408486031215611220578283fd5b61122984610fb8565b9250602084013567ffffffffffffffff811115611244578283fd5b61125086828701610fcf565b9497909650939450505050565b6000806020838503121561126f578182fd5b823567ffffffffffffffff811115611285578283fd5b61129185828601610fcf565b90969095509350505050565b6000602082840312156112ae578081fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610d93578182fd5b6000828483379101908152919050565b600082516112ff818460208701611423565b9190910192915050565b6000602082528251806020840152611328816040850160208701611423565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261138e578283fd5b83018035915067ffffffffffffffff8211156113a8578283fd5b60200191503681900382131561101157600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18336030181126112ff578182fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126112ff578182fd5b60005b8381101561143e578181015183820152602001611426565b8381111561062e5750506000910152565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561148d57634e487b7160e01b81526011600452602481fd5b506001019056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a2646970667358221220f7c425c3a3feed3f4634aa8703a8b0eb3a605b60d3041f062774fa50ba15f46364736f6c63430008020033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/packages/core/deployments/polygon/solcInputs/8647b3c46fdd7d95d4038ddf2cc1e589.json b/packages/core/deployments/polygon/solcInputs/8647b3c46fdd7d95d4038ddf2cc1e589.json new file mode 100644 index 0000000000..c61177feca --- /dev/null +++ b/packages/core/deployments/polygon/solcInputs/8647b3c46fdd7d95d4038ddf2cc1e589.json @@ -0,0 +1,785 @@ +{ + "language": "Solidity", + "sources": { + "@maticnetwork/fx-portal/contracts/lib/ExitPayloadReader.sol": { + "content": "pragma solidity ^0.8.0;\n\nimport {RLPReader} from \"./RLPReader.sol\";\n\nlibrary ExitPayloadReader {\n using RLPReader for bytes;\n using RLPReader for RLPReader.RLPItem;\n\n uint8 constant WORD_SIZE = 32;\n\n struct ExitPayload {\n RLPReader.RLPItem[] data;\n }\n\n struct Receipt {\n RLPReader.RLPItem[] data;\n bytes raw;\n uint256 logIndex;\n }\n\n struct Log {\n RLPReader.RLPItem data;\n RLPReader.RLPItem[] list;\n }\n\n struct LogTopics {\n RLPReader.RLPItem[] data;\n }\n\n // copy paste of private copy() from RLPReader to avoid changing of existing contracts\n function copy(\n uint256 src,\n uint256 dest,\n uint256 len\n ) private pure {\n if (len == 0) return;\n\n // copy as many word sizes as possible\n for (; len >= WORD_SIZE; len -= WORD_SIZE) {\n assembly {\n mstore(dest, mload(src))\n }\n\n src += WORD_SIZE;\n dest += WORD_SIZE;\n }\n \n if (len == 0) return;\n\n // left over bytes. Mask is used to remove unwanted bytes from the word\n uint256 mask = 256**(WORD_SIZE - len) - 1;\n assembly {\n let srcpart := and(mload(src), not(mask)) // zero out src\n let destpart := and(mload(dest), mask) // retrieve the bytes\n mstore(dest, or(destpart, srcpart))\n }\n }\n\n function toExitPayload(bytes memory data) internal pure returns (ExitPayload memory) {\n RLPReader.RLPItem[] memory payloadData = data.toRlpItem().toList();\n\n return ExitPayload(payloadData);\n }\n\n function getHeaderNumber(ExitPayload memory payload) internal pure returns (uint256) {\n return payload.data[0].toUint();\n }\n\n function getBlockProof(ExitPayload memory payload) internal pure returns (bytes memory) {\n return payload.data[1].toBytes();\n }\n\n function getBlockNumber(ExitPayload memory payload) internal pure returns (uint256) {\n return payload.data[2].toUint();\n }\n\n function getBlockTime(ExitPayload memory payload) internal pure returns (uint256) {\n return payload.data[3].toUint();\n }\n\n function getTxRoot(ExitPayload memory payload) internal pure returns (bytes32) {\n return bytes32(payload.data[4].toUint());\n }\n\n function getReceiptRoot(ExitPayload memory payload) internal pure returns (bytes32) {\n return bytes32(payload.data[5].toUint());\n }\n\n function getReceipt(ExitPayload memory payload) internal pure returns (Receipt memory receipt) {\n receipt.raw = payload.data[6].toBytes();\n RLPReader.RLPItem memory receiptItem = receipt.raw.toRlpItem();\n\n if (receiptItem.isList()) {\n // legacy tx\n receipt.data = receiptItem.toList();\n } else {\n // pop first byte before parsting receipt\n bytes memory typedBytes = receipt.raw;\n bytes memory result = new bytes(typedBytes.length - 1);\n uint256 srcPtr;\n uint256 destPtr;\n assembly {\n srcPtr := add(33, typedBytes)\n destPtr := add(0x20, result)\n }\n\n copy(srcPtr, destPtr, result.length);\n receipt.data = result.toRlpItem().toList();\n }\n\n receipt.logIndex = getReceiptLogIndex(payload);\n return receipt;\n }\n\n function getReceiptProof(ExitPayload memory payload) internal pure returns (bytes memory) {\n return payload.data[7].toBytes();\n }\n\n function getBranchMaskAsBytes(ExitPayload memory payload) internal pure returns (bytes memory) {\n return payload.data[8].toBytes();\n }\n\n function getBranchMaskAsUint(ExitPayload memory payload) internal pure returns (uint256) {\n return payload.data[8].toUint();\n }\n\n function getReceiptLogIndex(ExitPayload memory payload) internal pure returns (uint256) {\n return payload.data[9].toUint();\n }\n\n // Receipt methods\n function toBytes(Receipt memory receipt) internal pure returns (bytes memory) {\n return receipt.raw;\n }\n\n function getLog(Receipt memory receipt) internal pure returns (Log memory) {\n RLPReader.RLPItem memory logData = receipt.data[3].toList()[receipt.logIndex];\n return Log(logData, logData.toList());\n }\n\n // Log methods\n function getEmitter(Log memory log) internal pure returns (address) {\n return RLPReader.toAddress(log.list[0]);\n }\n\n function getTopics(Log memory log) internal pure returns (LogTopics memory) {\n return LogTopics(log.list[1].toList());\n }\n\n function getData(Log memory log) internal pure returns (bytes memory) {\n return log.list[2].toBytes();\n }\n\n function toRlpBytes(Log memory log) internal pure returns (bytes memory) {\n return log.data.toRlpBytes();\n }\n\n // LogTopics methods\n function getField(LogTopics memory topics, uint256 index) internal pure returns (RLPReader.RLPItem memory) {\n return topics.data[index];\n }\n}\n" + }, + "@maticnetwork/fx-portal/contracts/lib/Merkle.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nlibrary Merkle {\n function checkMembership(\n bytes32 leaf,\n uint256 index,\n bytes32 rootHash,\n bytes memory proof\n ) internal pure returns (bool) {\n require(proof.length % 32 == 0, \"Invalid proof length\");\n uint256 proofHeight = proof.length / 32;\n // Proof of size n means, height of the tree is n+1.\n // In a tree of height n+1, max #leafs possible is 2 ^ n\n require(index < 2**proofHeight, \"Leaf index is too big\");\n\n bytes32 proofElement;\n bytes32 computedHash = leaf;\n for (uint256 i = 32; i <= proof.length; i += 32) {\n assembly {\n proofElement := mload(add(proof, i))\n }\n\n if (index % 2 == 0) {\n computedHash = keccak256(abi.encodePacked(computedHash, proofElement));\n } else {\n computedHash = keccak256(abi.encodePacked(proofElement, computedHash));\n }\n\n index = index / 2;\n }\n return computedHash == rootHash;\n }\n}\n" + }, + "@maticnetwork/fx-portal/contracts/lib/MerklePatriciaProof.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {RLPReader} from \"./RLPReader.sol\";\n\nlibrary MerklePatriciaProof {\n /*\n * @dev Verifies a merkle patricia proof.\n * @param value The terminating value in the trie.\n * @param encodedPath The path in the trie leading to value.\n * @param rlpParentNodes The rlp encoded stack of nodes.\n * @param root The root hash of the trie.\n * @return The boolean validity of the proof.\n */\n function verify(\n bytes memory value,\n bytes memory encodedPath,\n bytes memory rlpParentNodes,\n bytes32 root\n ) internal pure returns (bool) {\n RLPReader.RLPItem memory item = RLPReader.toRlpItem(rlpParentNodes);\n RLPReader.RLPItem[] memory parentNodes = RLPReader.toList(item);\n\n bytes memory currentNode;\n RLPReader.RLPItem[] memory currentNodeList;\n\n bytes32 nodeKey = root;\n uint256 pathPtr = 0;\n\n bytes memory path = _getNibbleArray(encodedPath);\n if (path.length == 0) {\n return false;\n }\n\n for (uint256 i = 0; i < parentNodes.length; i++) {\n if (pathPtr > path.length) {\n return false;\n }\n\n currentNode = RLPReader.toRlpBytes(parentNodes[i]);\n if (nodeKey != keccak256(currentNode)) {\n return false;\n }\n currentNodeList = RLPReader.toList(parentNodes[i]);\n\n if (currentNodeList.length == 17) {\n if (pathPtr == path.length) {\n if (keccak256(RLPReader.toBytes(currentNodeList[16])) == keccak256(value)) {\n return true;\n } else {\n return false;\n }\n }\n\n uint8 nextPathNibble = uint8(path[pathPtr]);\n if (nextPathNibble > 16) {\n return false;\n }\n nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[nextPathNibble]));\n pathPtr += 1;\n } else if (currentNodeList.length == 2) {\n uint256 traversed = _nibblesToTraverse(RLPReader.toBytes(currentNodeList[0]), path, pathPtr);\n if (pathPtr + traversed == path.length) {\n //leaf node\n if (keccak256(RLPReader.toBytes(currentNodeList[1])) == keccak256(value)) {\n return true;\n } else {\n return false;\n }\n }\n\n //extension node\n if (traversed == 0) {\n return false;\n }\n\n pathPtr += traversed;\n nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[1]));\n } else {\n return false;\n }\n }\n }\n\n function _nibblesToTraverse(\n bytes memory encodedPartialPath,\n bytes memory path,\n uint256 pathPtr\n ) private pure returns (uint256) {\n uint256 len = 0;\n // encodedPartialPath has elements that are each two hex characters (1 byte), but partialPath\n // and slicedPath have elements that are each one hex character (1 nibble)\n bytes memory partialPath = _getNibbleArray(encodedPartialPath);\n bytes memory slicedPath = new bytes(partialPath.length);\n\n // pathPtr counts nibbles in path\n // partialPath.length is a number of nibbles\n for (uint256 i = pathPtr; i < pathPtr + partialPath.length; i++) {\n bytes1 pathNibble = path[i];\n slicedPath[i - pathPtr] = pathNibble;\n }\n\n if (keccak256(partialPath) == keccak256(slicedPath)) {\n len = partialPath.length;\n } else {\n len = 0;\n }\n return len;\n }\n\n // bytes b must be hp encoded\n function _getNibbleArray(bytes memory b) internal pure returns (bytes memory) {\n bytes memory nibbles = \"\";\n if (b.length > 0) {\n uint8 offset;\n uint8 hpNibble = uint8(_getNthNibbleOfBytes(0, b));\n if (hpNibble == 1 || hpNibble == 3) {\n nibbles = new bytes(b.length * 2 - 1);\n bytes1 oddNibble = _getNthNibbleOfBytes(1, b);\n nibbles[0] = oddNibble;\n offset = 1;\n } else {\n nibbles = new bytes(b.length * 2 - 2);\n offset = 0;\n }\n\n for (uint256 i = offset; i < nibbles.length; i++) {\n nibbles[i] = _getNthNibbleOfBytes(i - offset + 2, b);\n }\n }\n return nibbles;\n }\n\n function _getNthNibbleOfBytes(uint256 n, bytes memory str) private pure returns (bytes1) {\n return bytes1(n % 2 == 0 ? uint8(str[n / 2]) / 0x10 : uint8(str[n / 2]) % 0x10);\n }\n}\n" + }, + "@maticnetwork/fx-portal/contracts/lib/RLPReader.sol": { + "content": "/*\n * @author Hamdi Allam hamdi.allam97@gmail.com\n * Please reach out with any questions or concerns\n */\npragma solidity ^0.8.0;\n\nlibrary RLPReader {\n uint8 constant STRING_SHORT_START = 0x80;\n uint8 constant STRING_LONG_START = 0xb8;\n uint8 constant LIST_SHORT_START = 0xc0;\n uint8 constant LIST_LONG_START = 0xf8;\n uint8 constant WORD_SIZE = 32;\n\n struct RLPItem {\n uint256 len;\n uint256 memPtr;\n }\n\n struct Iterator {\n RLPItem item; // Item that's being iterated over.\n uint256 nextPtr; // Position of the next item in the list.\n }\n\n /*\n * @dev Returns the next element in the iteration. Reverts if it has not next element.\n * @param self The iterator.\n * @return The next element in the iteration.\n */\n function next(Iterator memory self) internal pure returns (RLPItem memory) {\n require(hasNext(self));\n\n uint256 ptr = self.nextPtr;\n uint256 itemLength = _itemLength(ptr);\n self.nextPtr = ptr + itemLength;\n\n return RLPItem(itemLength, ptr);\n }\n\n /*\n * @dev Returns true if the iteration has more elements.\n * @param self The iterator.\n * @return true if the iteration has more elements.\n */\n function hasNext(Iterator memory self) internal pure returns (bool) {\n RLPItem memory item = self.item;\n return self.nextPtr < item.memPtr + item.len;\n }\n\n /*\n * @param item RLP encoded bytes\n */\n function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) {\n uint256 memPtr;\n assembly {\n memPtr := add(item, 0x20)\n }\n\n return RLPItem(item.length, memPtr);\n }\n\n /*\n * @dev Create an iterator. Reverts if item is not a list.\n * @param self The RLP item.\n * @return An 'Iterator' over the item.\n */\n function iterator(RLPItem memory self) internal pure returns (Iterator memory) {\n require(isList(self));\n\n uint256 ptr = self.memPtr + _payloadOffset(self.memPtr);\n return Iterator(self, ptr);\n }\n\n /*\n * @param item RLP encoded bytes\n */\n function rlpLen(RLPItem memory item) internal pure returns (uint256) {\n return item.len;\n }\n\n /*\n * @param item RLP encoded bytes\n */\n function payloadLen(RLPItem memory item) internal pure returns (uint256) {\n return item.len - _payloadOffset(item.memPtr);\n }\n\n /*\n * @param item RLP encoded list in bytes\n */\n function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) {\n require(isList(item));\n\n uint256 items = numItems(item);\n RLPItem[] memory result = new RLPItem[](items);\n\n uint256 memPtr = item.memPtr + _payloadOffset(item.memPtr);\n uint256 dataLen;\n for (uint256 i = 0; i < items; i++) {\n dataLen = _itemLength(memPtr);\n result[i] = RLPItem(dataLen, memPtr);\n memPtr = memPtr + dataLen;\n }\n\n return result;\n }\n\n // @return indicator whether encoded payload is a list. negate this function call for isData.\n function isList(RLPItem memory item) internal pure returns (bool) {\n if (item.len == 0) return false;\n\n uint8 byte0;\n uint256 memPtr = item.memPtr;\n assembly {\n byte0 := byte(0, mload(memPtr))\n }\n\n if (byte0 < LIST_SHORT_START) return false;\n return true;\n }\n\n /*\n * @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory.\n * @return keccak256 hash of RLP encoded bytes.\n */\n function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) {\n uint256 ptr = item.memPtr;\n uint256 len = item.len;\n bytes32 result;\n assembly {\n result := keccak256(ptr, len)\n }\n return result;\n }\n\n function payloadLocation(RLPItem memory item) internal pure returns (uint256, uint256) {\n uint256 offset = _payloadOffset(item.memPtr);\n uint256 memPtr = item.memPtr + offset;\n uint256 len = item.len - offset; // data length\n return (memPtr, len);\n }\n\n /*\n * @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory.\n * @return keccak256 hash of the item payload.\n */\n function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) {\n (uint256 memPtr, uint256 len) = payloadLocation(item);\n bytes32 result;\n assembly {\n result := keccak256(memPtr, len)\n }\n return result;\n }\n\n /** RLPItem conversions into data types **/\n\n // @returns raw rlp encoding in bytes\n function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) {\n bytes memory result = new bytes(item.len);\n if (result.length == 0) return result;\n\n uint256 ptr;\n assembly {\n ptr := add(0x20, result)\n }\n\n copy(item.memPtr, ptr, item.len);\n return result;\n }\n\n // any non-zero byte is considered true\n function toBoolean(RLPItem memory item) internal pure returns (bool) {\n require(item.len == 1);\n uint256 result;\n uint256 memPtr = item.memPtr;\n assembly {\n result := byte(0, mload(memPtr))\n }\n\n return result == 0 ? false : true;\n }\n\n function toAddress(RLPItem memory item) internal pure returns (address) {\n // 1 byte for the length prefix\n require(item.len == 21);\n\n return address(uint160(toUint(item)));\n }\n\n function toUint(RLPItem memory item) internal pure returns (uint256) {\n require(item.len > 0 && item.len <= 33);\n\n uint256 offset = _payloadOffset(item.memPtr);\n uint256 len = item.len - offset;\n\n uint256 result;\n uint256 memPtr = item.memPtr + offset;\n assembly {\n result := mload(memPtr)\n\n // shfit to the correct location if neccesary\n if lt(len, 32) {\n result := div(result, exp(256, sub(32, len)))\n }\n }\n\n return result;\n }\n\n // enforces 32 byte length\n function toUintStrict(RLPItem memory item) internal pure returns (uint256) {\n // one byte prefix\n require(item.len == 33);\n\n uint256 result;\n uint256 memPtr = item.memPtr + 1;\n assembly {\n result := mload(memPtr)\n }\n\n return result;\n }\n\n function toBytes(RLPItem memory item) internal pure returns (bytes memory) {\n require(item.len > 0);\n\n uint256 offset = _payloadOffset(item.memPtr);\n uint256 len = item.len - offset; // data length\n bytes memory result = new bytes(len);\n\n uint256 destPtr;\n assembly {\n destPtr := add(0x20, result)\n }\n\n copy(item.memPtr + offset, destPtr, len);\n return result;\n }\n\n /*\n * Private Helpers\n */\n\n // @return number of payload items inside an encoded list.\n function numItems(RLPItem memory item) private pure returns (uint256) {\n if (item.len == 0) return 0;\n\n uint256 count = 0;\n uint256 currPtr = item.memPtr + _payloadOffset(item.memPtr);\n uint256 endPtr = item.memPtr + item.len;\n while (currPtr < endPtr) {\n currPtr = currPtr + _itemLength(currPtr); // skip over an item\n count++;\n }\n\n return count;\n }\n\n // @return entire rlp item byte length\n function _itemLength(uint256 memPtr) private pure returns (uint256) {\n uint256 itemLen;\n uint256 byte0;\n assembly {\n byte0 := byte(0, mload(memPtr))\n }\n\n if (byte0 < STRING_SHORT_START) itemLen = 1;\n else if (byte0 < STRING_LONG_START) itemLen = byte0 - STRING_SHORT_START + 1;\n else if (byte0 < LIST_SHORT_START) {\n assembly {\n let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is\n memPtr := add(memPtr, 1) // skip over the first byte\n /* 32 byte word size */\n let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len\n itemLen := add(dataLen, add(byteLen, 1))\n }\n } else if (byte0 < LIST_LONG_START) {\n itemLen = byte0 - LIST_SHORT_START + 1;\n } else {\n assembly {\n let byteLen := sub(byte0, 0xf7)\n memPtr := add(memPtr, 1)\n\n let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length\n itemLen := add(dataLen, add(byteLen, 1))\n }\n }\n\n return itemLen;\n }\n\n // @return number of bytes until the data\n function _payloadOffset(uint256 memPtr) private pure returns (uint256) {\n uint256 byte0;\n assembly {\n byte0 := byte(0, mload(memPtr))\n }\n\n if (byte0 < STRING_SHORT_START) return 0;\n else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)) return 1;\n else if (byte0 < LIST_SHORT_START)\n // being explicit\n return byte0 - (STRING_LONG_START - 1) + 1;\n else return byte0 - (LIST_LONG_START - 1) + 1;\n }\n\n /*\n * @param src Pointer to source\n * @param dest Pointer to destination\n * @param len Amount of memory to copy from the source\n */\n function copy(\n uint256 src,\n uint256 dest,\n uint256 len\n ) private pure {\n if (len == 0) return;\n\n // copy as many word sizes as possible\n for (; len >= WORD_SIZE; len -= WORD_SIZE) {\n assembly {\n mstore(dest, mload(src))\n }\n\n src += WORD_SIZE;\n dest += WORD_SIZE;\n }\n\n if (len == 0) return;\n\n // left over bytes. Mask is used to remove unwanted bytes from the word\n uint256 mask = 256**(WORD_SIZE - len) - 1;\n\n assembly {\n let srcpart := and(mload(src), not(mask)) // zero out src\n let destpart := and(mload(dest), mask) // retrieve the bytes\n mstore(dest, or(destpart, srcpart))\n }\n }\n}\n" + }, + "@maticnetwork/fx-portal/contracts/tunnel/FxBaseChildTunnel.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n// IFxMessageProcessor represents interface to process message\ninterface IFxMessageProcessor {\n function processMessageFromRoot(\n uint256 stateId,\n address rootMessageSender,\n bytes calldata data\n ) external;\n}\n\n/**\n * @notice Mock child tunnel contract to receive and send message from L2\n */\nabstract contract FxBaseChildTunnel is IFxMessageProcessor {\n // MessageTunnel on L1 will get data from this event\n event MessageSent(bytes message);\n\n // fx child\n address public fxChild;\n\n // fx root tunnel\n address public fxRootTunnel;\n\n constructor(address _fxChild) {\n fxChild = _fxChild;\n }\n\n // Sender must be fxRootTunnel in case of ERC20 tunnel\n modifier validateSender(address sender) {\n require(sender == fxRootTunnel, \"FxBaseChildTunnel: INVALID_SENDER_FROM_ROOT\");\n _;\n }\n\n // set fxRootTunnel if not set already\n function setFxRootTunnel(address _fxRootTunnel) external virtual {\n require(fxRootTunnel == address(0x0), \"FxBaseChildTunnel: ROOT_TUNNEL_ALREADY_SET\");\n fxRootTunnel = _fxRootTunnel;\n }\n\n function processMessageFromRoot(\n uint256 stateId,\n address rootMessageSender,\n bytes calldata data\n ) external override {\n require(msg.sender == fxChild, \"FxBaseChildTunnel: INVALID_SENDER\");\n _processMessageFromRoot(stateId, rootMessageSender, data);\n }\n\n /**\n * @notice Emit message that can be received on Root Tunnel\n * @dev Call the internal function when need to emit message\n * @param message bytes message that will be sent to Root Tunnel\n * some message examples -\n * abi.encode(tokenId);\n * abi.encode(tokenId, tokenMetadata);\n * abi.encode(messageType, messageData);\n */\n function _sendMessageToRoot(bytes memory message) internal {\n emit MessageSent(message);\n }\n\n /**\n * @notice Process message received from Root Tunnel\n * @dev function needs to be implemented to handle message as per requirement\n * This is called by onStateReceive function.\n * Since it is called via a system call, any event will not be emitted during its execution.\n * @param stateId unique state id\n * @param sender root message sender\n * @param message bytes message that was sent from Root Tunnel\n */\n function _processMessageFromRoot(\n uint256 stateId,\n address sender,\n bytes memory message\n ) internal virtual;\n}\n" + }, + "@maticnetwork/fx-portal/contracts/tunnel/FxBaseRootTunnel.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {RLPReader} from \"../lib/RLPReader.sol\";\nimport {MerklePatriciaProof} from \"../lib/MerklePatriciaProof.sol\";\nimport {Merkle} from \"../lib/Merkle.sol\";\nimport \"../lib/ExitPayloadReader.sol\";\n\ninterface IFxStateSender {\n function sendMessageToChild(address _receiver, bytes calldata _data) external;\n}\n\ncontract ICheckpointManager {\n struct HeaderBlock {\n bytes32 root;\n uint256 start;\n uint256 end;\n uint256 createdAt;\n address proposer;\n }\n\n /**\n * @notice mapping of checkpoint header numbers to block details\n * @dev These checkpoints are submited by plasma contracts\n */\n mapping(uint256 => HeaderBlock) public headerBlocks;\n}\n\nabstract contract FxBaseRootTunnel {\n using RLPReader for RLPReader.RLPItem;\n using Merkle for bytes32;\n using ExitPayloadReader for bytes;\n using ExitPayloadReader for ExitPayloadReader.ExitPayload;\n using ExitPayloadReader for ExitPayloadReader.Log;\n using ExitPayloadReader for ExitPayloadReader.LogTopics;\n using ExitPayloadReader for ExitPayloadReader.Receipt;\n\n // keccak256(MessageSent(bytes))\n bytes32 public constant SEND_MESSAGE_EVENT_SIG = 0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036;\n\n // state sender contract\n IFxStateSender public fxRoot;\n // root chain manager\n ICheckpointManager public checkpointManager;\n // child tunnel contract which receives and sends messages\n address public fxChildTunnel;\n\n // storage to avoid duplicate exits\n mapping(bytes32 => bool) public processedExits;\n\n constructor(address _checkpointManager, address _fxRoot) {\n checkpointManager = ICheckpointManager(_checkpointManager);\n fxRoot = IFxStateSender(_fxRoot);\n }\n\n // set fxChildTunnel if not set already\n function setFxChildTunnel(address _fxChildTunnel) public virtual {\n require(fxChildTunnel == address(0x0), \"FxBaseRootTunnel: CHILD_TUNNEL_ALREADY_SET\");\n fxChildTunnel = _fxChildTunnel;\n }\n\n /**\n * @notice Send bytes message to Child Tunnel\n * @param message bytes message that will be sent to Child Tunnel\n * some message examples -\n * abi.encode(tokenId);\n * abi.encode(tokenId, tokenMetadata);\n * abi.encode(messageType, messageData);\n */\n function _sendMessageToChild(bytes memory message) internal {\n fxRoot.sendMessageToChild(fxChildTunnel, message);\n }\n\n function _validateAndExtractMessage(bytes memory inputData) internal returns (bytes memory) {\n ExitPayloadReader.ExitPayload memory payload = inputData.toExitPayload();\n\n bytes memory branchMaskBytes = payload.getBranchMaskAsBytes();\n uint256 blockNumber = payload.getBlockNumber();\n // checking if exit has already been processed\n // unique exit is identified using hash of (blockNumber, branchMask, receiptLogIndex)\n bytes32 exitHash = keccak256(\n abi.encodePacked(\n blockNumber,\n // first 2 nibbles are dropped while generating nibble array\n // this allows branch masks that are valid but bypass exitHash check (changing first 2 nibbles only)\n // so converting to nibble array and then hashing it\n MerklePatriciaProof._getNibbleArray(branchMaskBytes),\n payload.getReceiptLogIndex()\n )\n );\n require(processedExits[exitHash] == false, \"FxRootTunnel: EXIT_ALREADY_PROCESSED\");\n processedExits[exitHash] = true;\n\n ExitPayloadReader.Receipt memory receipt = payload.getReceipt();\n ExitPayloadReader.Log memory log = receipt.getLog();\n\n // check child tunnel\n require(fxChildTunnel == log.getEmitter(), \"FxRootTunnel: INVALID_FX_CHILD_TUNNEL\");\n\n bytes32 receiptRoot = payload.getReceiptRoot();\n // verify receipt inclusion\n require(\n MerklePatriciaProof.verify(receipt.toBytes(), branchMaskBytes, payload.getReceiptProof(), receiptRoot),\n \"FxRootTunnel: INVALID_RECEIPT_PROOF\"\n );\n\n // verify checkpoint inclusion\n _checkBlockMembershipInCheckpoint(\n blockNumber,\n payload.getBlockTime(),\n payload.getTxRoot(),\n receiptRoot,\n payload.getHeaderNumber(),\n payload.getBlockProof()\n );\n\n ExitPayloadReader.LogTopics memory topics = log.getTopics();\n\n require(\n bytes32(topics.getField(0).toUint()) == SEND_MESSAGE_EVENT_SIG, // topic0 is event sig\n \"FxRootTunnel: INVALID_SIGNATURE\"\n );\n\n // received message data\n bytes memory message = abi.decode(log.getData(), (bytes)); // event decodes params again, so decoding bytes to get message\n return message;\n }\n\n function _checkBlockMembershipInCheckpoint(\n uint256 blockNumber,\n uint256 blockTime,\n bytes32 txRoot,\n bytes32 receiptRoot,\n uint256 headerNumber,\n bytes memory blockProof\n ) private view returns (uint256) {\n (bytes32 headerRoot, uint256 startBlock, , uint256 createdAt, ) = checkpointManager.headerBlocks(headerNumber);\n\n require(\n keccak256(abi.encodePacked(blockNumber, blockTime, txRoot, receiptRoot)).checkMembership(\n blockNumber - startBlock,\n headerRoot,\n blockProof\n ),\n \"FxRootTunnel: INVALID_HEADER\"\n );\n return createdAt;\n }\n\n /**\n * @notice receive message from L2 to L1, validated by proof\n * @dev This function verifies if the transaction actually happened on child chain\n *\n * @param inputData RLP encoded data of the reference tx containing following list of fields\n * 0 - headerNumber - Checkpoint header block number containing the reference tx\n * 1 - blockProof - Proof that the block header (in the child chain) is a leaf in the submitted merkle root\n * 2 - blockNumber - Block number containing the reference tx on child chain\n * 3 - blockTime - Reference tx block time\n * 4 - txRoot - Transactions root of block\n * 5 - receiptRoot - Receipts root of block\n * 6 - receipt - Receipt of the reference transaction\n * 7 - receiptProof - Merkle proof of the reference receipt\n * 8 - branchMask - 32 bits denoting the path of receipt in merkle tree\n * 9 - receiptLogIndex - Log Index to read from the receipt\n */\n function receiveMessage(bytes memory inputData) public virtual {\n bytes memory message = _validateAndExtractMessage(inputData);\n _processMessageFromChild(message);\n }\n\n /**\n * @notice Process message received from Child Tunnel\n * @dev function needs to be implemented to handle message as per requirement\n * This is called by onStateReceive function.\n * Since it is called via a system call, any event will not be emitted during its execution.\n * @param message bytes message that was sent from Child Tunnel\n */\n function _processMessageFromChild(bytes memory message) internal virtual;\n}\n" + }, + "@openzeppelin/contracts-0.8/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role, _msgSender());\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(uint160(account), 20),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/access/AccessControlEnumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerable.sol\";\nimport \"./AccessControl.sol\";\nimport \"../utils/structs/EnumerableSet.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-0.8/access/IAccessControlEnumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerable is IAccessControl {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-0.8/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/security/Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n constructor() {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n require(!paused(), \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n require(paused(), \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: balance query for the zero address\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(address[] memory accounts, uint256[] memory ids)\n public\n view\n virtual\n override\n returns (uint256[] memory)\n {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(\n address from,\n uint256 id,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(\n address from,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits a {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/token/ERC1155/extensions/ERC1155Burnable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Burnable is ERC1155 {\n function burn(\n address account,\n uint256 id,\n uint256 value\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory values\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/token/ERC1155/extensions/ERC1155Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/ERC1155Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155.sol\";\nimport \"../../../security/Pausable.sol\";\n\n/**\n * @dev ERC1155 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155Pausable is ERC1155, Pausable {\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual override {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n require(!paused(), \"ERC1155Pausable: token transfer while paused\");\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-0.8/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)\n external\n view\n returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts-0.8/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n @dev Handles the receipt of a single ERC1155 token type. This function is\n called at the end of a `safeTransferFrom` after the balance has been updated.\n To accept the transfer, this must return\n `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n (i.e. 0xf23a6e61, or its own function selector).\n @param operator The address which initiated the transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param id The ID of the token being transferred\n @param value The amount of tokens being transferred\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n @dev Handles the receipt of a multiple ERC1155 token types. This function\n is called at the end of a `safeBatchTransferFrom` after the balances have\n been updated. To accept the transfer(s), this must return\n `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n (i.e. 0xbc197c81, or its own function selector).\n @param operator The address which initiated the batch transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param ids An array containing ids of each token being transferred (order and length must match values array)\n @param values An array containing amounts of each token being transferred (order and length must match ids array)\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-0.8/token/ERC1155/presets/ERC1155PresetMinterPauser.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/presets/ERC1155PresetMinterPauser.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155.sol\";\nimport \"../extensions/ERC1155Burnable.sol\";\nimport \"../extensions/ERC1155Pausable.sol\";\nimport \"../../../access/AccessControlEnumerable.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev {ERC1155} token, including:\n *\n * - ability for holders to burn (destroy) their tokens\n * - a minter role that allows for token minting (creation)\n * - a pauser role that allows to stop all token transfers\n *\n * This contract uses {AccessControl} to lock permissioned functions using the\n * different roles - head to its documentation for details.\n *\n * The account that deploys the contract will be granted the minter and pauser\n * roles, as well as the default admin role, which will let it grant both minter\n * and pauser roles to other accounts.\n */\ncontract ERC1155PresetMinterPauser is Context, AccessControlEnumerable, ERC1155Burnable, ERC1155Pausable {\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant PAUSER_ROLE = keccak256(\"PAUSER_ROLE\");\n\n /**\n * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE`, and `PAUSER_ROLE` to the account that\n * deploys the contract.\n */\n constructor(string memory uri) ERC1155(uri) {\n _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());\n\n _setupRole(MINTER_ROLE, _msgSender());\n _setupRole(PAUSER_ROLE, _msgSender());\n }\n\n /**\n * @dev Creates `amount` new tokens for `to`, of token type `id`.\n *\n * See {ERC1155-_mint}.\n *\n * Requirements:\n *\n * - the caller must have the `MINTER_ROLE`.\n */\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual {\n require(hasRole(MINTER_ROLE, _msgSender()), \"ERC1155PresetMinterPauser: must have minter role to mint\");\n\n _mint(to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] variant of {mint}.\n */\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual {\n require(hasRole(MINTER_ROLE, _msgSender()), \"ERC1155PresetMinterPauser: must have minter role to mint\");\n\n _mintBatch(to, ids, amounts, data);\n }\n\n /**\n * @dev Pauses all token transfers.\n *\n * See {ERC1155Pausable} and {Pausable-_pause}.\n *\n * Requirements:\n *\n * - the caller must have the `PAUSER_ROLE`.\n */\n function pause() public virtual {\n require(hasRole(PAUSER_ROLE, _msgSender()), \"ERC1155PresetMinterPauser: must have pauser role to pause\");\n _pause();\n }\n\n /**\n * @dev Unpauses all token transfers.\n *\n * See {ERC1155Pausable} and {Pausable-_unpause}.\n *\n * Requirements:\n *\n * - the caller must have the `PAUSER_ROLE`.\n */\n function unpause() public virtual {\n require(hasRole(PAUSER_ROLE, _msgSender()), \"ERC1155PresetMinterPauser: must have pauser role to unpause\");\n _unpause();\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(AccessControlEnumerable, ERC1155)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual override(ERC1155, ERC1155Pausable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/token/ERC1155/utils/ERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Receiver.sol\";\nimport \"../../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens 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 amount\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, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been 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 _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts-0.8/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-0.8/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-0.8/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts-0.8/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.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 ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings 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 constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).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: balance query for the zero address\");\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: owner query for nonexistent token\");\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 require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\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 overriden 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 = ERC721.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 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 require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\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: transfer caller is not 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: transfer caller is not 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 require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, 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\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 = ERC721.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\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(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\");\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\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits a {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits a {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 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 IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\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" + }, + "@openzeppelin/contracts-0.8/token/ERC721/extensions/ERC721Burnable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\n */\nabstract contract ERC721Burnable is Context, ERC721 {\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), \"ERC721Burnable: caller is not owner nor approved\");\n _burn(tokenId);\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/token/ERC721/extensions/ERC721Enumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721.sol\";\nimport \"./IERC721Enumerable.sol\";\n\n/**\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\n * enumerability of all the token ids in the contract as well as all token ids owned by each\n * account.\n */\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\n // Mapping from owner to list of owned token IDs\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\n\n // Mapping from token ID to index of the owner tokens list\n mapping(uint256 => uint256) private _ownedTokensIndex;\n\n // Array with all token ids, used for enumeration\n uint256[] private _allTokens;\n\n // Mapping from token id to position in the allTokens array\n mapping(uint256 => uint256) private _allTokensIndex;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721.balanceOf(owner), \"ERC721Enumerable: owner index out of bounds\");\n return _ownedTokens[owner][index];\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _allTokens.length;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721Enumerable.totalSupply(), \"ERC721Enumerable: global index out of bounds\");\n return _allTokens[index];\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` cannot be the zero address.\n * - `to` cannot be the zero address.\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 override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n if (from == address(0)) {\n _addTokenToAllTokensEnumeration(tokenId);\n } else if (from != to) {\n _removeTokenFromOwnerEnumeration(from, tokenId);\n }\n if (to == address(0)) {\n _removeTokenFromAllTokensEnumeration(tokenId);\n } else if (to != from) {\n _addTokenToOwnerEnumeration(to, tokenId);\n }\n }\n\n /**\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\n * @param to address representing the new owner of the given token ID\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\n */\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\n uint256 length = ERC721.balanceOf(to);\n _ownedTokens[to][length] = tokenId;\n _ownedTokensIndex[tokenId] = length;\n }\n\n /**\n * @dev Private function to add a token to this extension's token tracking data structures.\n * @param tokenId uint256 ID of the token to be added to the tokens list\n */\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\n _allTokensIndex[tokenId] = _allTokens.length;\n _allTokens.push(tokenId);\n }\n\n /**\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\n * @param from address representing the previous owner of the given token ID\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\n */\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary\n if (tokenIndex != lastTokenIndex) {\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\n\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n }\n\n // This also deletes the contents at the last position of the array\n delete _ownedTokensIndex[tokenId];\n delete _ownedTokens[from][lastTokenIndex];\n }\n\n /**\n * @dev Private function to remove a token from this extension's token tracking data structures.\n * This has O(1) time complexity, but alters the order of the _allTokens array.\n * @param tokenId uint256 ID of the token to be removed from the tokens list\n */\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = _allTokens.length - 1;\n uint256 tokenIndex = _allTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\n uint256 lastTokenId = _allTokens[lastTokenIndex];\n\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n\n // This also deletes the contents at the last position of the array\n delete _allTokensIndex[tokenId];\n _allTokens.pop();\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/token/ERC721/extensions/ERC721Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721.sol\";\nimport \"../../../security/Pausable.sol\";\n\n/**\n * @dev ERC721 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC721Pausable is ERC721, Pausable {\n /**\n * @dev See {ERC721-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n require(!paused(), \"ERC721Pausable: token transfer while paused\");\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/token/ERC721/extensions/IERC721Enumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-0.8/token/ERC721/extensions/IERC721Metadata.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 \"../IERC721.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 IERC721Metadata is IERC721 {\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-0.8/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\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`, 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 be 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 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 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 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 /**\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" + }, + "@openzeppelin/contracts-0.8/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (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 IERC721Receiver {\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 `IERC721.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-0.8/token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721.sol\";\nimport \"../extensions/ERC721Enumerable.sol\";\nimport \"../extensions/ERC721Burnable.sol\";\nimport \"../extensions/ERC721Pausable.sol\";\nimport \"../../../access/AccessControlEnumerable.sol\";\nimport \"../../../utils/Context.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev {ERC721} token, including:\n *\n * - ability for holders to burn (destroy) their tokens\n * - a minter role that allows for token minting (creation)\n * - a pauser role that allows to stop all token transfers\n * - token ID and URI autogeneration\n *\n * This contract uses {AccessControl} to lock permissioned functions using the\n * different roles - head to its documentation for details.\n *\n * The account that deploys the contract will be granted the minter and pauser\n * roles, as well as the default admin role, which will let it grant both minter\n * and pauser roles to other accounts.\n */\ncontract ERC721PresetMinterPauserAutoId is\n Context,\n AccessControlEnumerable,\n ERC721Enumerable,\n ERC721Burnable,\n ERC721Pausable\n{\n using Counters for Counters.Counter;\n\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant PAUSER_ROLE = keccak256(\"PAUSER_ROLE\");\n\n Counters.Counter private _tokenIdTracker;\n\n string private _baseTokenURI;\n\n /**\n * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the\n * account that deploys the contract.\n *\n * Token URIs will be autogenerated based on `baseURI` and their token IDs.\n * See {ERC721-tokenURI}.\n */\n constructor(\n string memory name,\n string memory symbol,\n string memory baseTokenURI\n ) ERC721(name, symbol) {\n _baseTokenURI = baseTokenURI;\n\n _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());\n\n _setupRole(MINTER_ROLE, _msgSender());\n _setupRole(PAUSER_ROLE, _msgSender());\n }\n\n function _baseURI() internal view virtual override returns (string memory) {\n return _baseTokenURI;\n }\n\n /**\n * @dev Creates a new token for `to`. Its token ID will be automatically\n * assigned (and available on the emitted {IERC721-Transfer} event), and the token\n * URI autogenerated based on the base URI passed at construction.\n *\n * See {ERC721-_mint}.\n *\n * Requirements:\n *\n * - the caller must have the `MINTER_ROLE`.\n */\n function mint(address to) public virtual {\n require(hasRole(MINTER_ROLE, _msgSender()), \"ERC721PresetMinterPauserAutoId: must have minter role to mint\");\n\n // We cannot just use balanceOf to create the new tokenId because tokens\n // can be burned (destroyed), so we need a separate counter.\n _mint(to, _tokenIdTracker.current());\n _tokenIdTracker.increment();\n }\n\n /**\n * @dev Pauses all token transfers.\n *\n * See {ERC721Pausable} and {Pausable-_pause}.\n *\n * Requirements:\n *\n * - the caller must have the `PAUSER_ROLE`.\n */\n function pause() public virtual {\n require(hasRole(PAUSER_ROLE, _msgSender()), \"ERC721PresetMinterPauserAutoId: must have pauser role to pause\");\n _pause();\n }\n\n /**\n * @dev Unpauses all token transfers.\n *\n * See {ERC721Pausable} and {Pausable-_unpause}.\n *\n * Requirements:\n *\n * - the caller must have the `PAUSER_ROLE`.\n */\n function unpause() public virtual {\n require(hasRole(PAUSER_ROLE, _msgSender()), \"ERC721PresetMinterPauserAutoId: must have pauser role to unpause\");\n _unpause();\n }\n\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual override(ERC721, ERC721Enumerable, ERC721Pausable) {\n super._beforeTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(AccessControlEnumerable, ERC721, ERC721Enumerable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\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 function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 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 Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(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\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-0.8/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\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 Context {\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" + }, + "@openzeppelin/contracts-0.8/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/utils/cryptography/draft-EIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s;\n uint8 v;\n assembly {\n s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\n v := add(shr(255, vs), 27)\n }\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/utils/cryptography/MerkleProof.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/MerkleProof.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev These functions deal with verification of Merkle Trees proofs.\n *\n * The proofs can be generated using the JavaScript library\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\n *\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\n */\nlibrary MerkleProof {\n /**\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\n * defined by `root`. For this, a `proof` must be provided, containing\n * sibling hashes on the branch from the leaf to the root of the tree. Each\n * pair of leaves and each pair of pre-images are assumed to be sorted.\n */\n function verify(\n bytes32[] memory proof,\n bytes32 root,\n bytes32 leaf\n ) internal pure returns (bool) {\n return processProof(proof, leaf) == root;\n }\n\n /**\n * @dev Returns the rebuilt hash obtained by traversing a Merklee tree up\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\n * hash matches the root of the tree. When processing the proof, the pairs\n * of leafs & pre-images are assumed to be sorted.\n *\n * _Available since v4.4._\n */\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\n bytes32 computedHash = leaf;\n for (uint256 i = 0; i < proof.length; i++) {\n bytes32 proofElement = proof[i];\n if (computedHash <= proofElement) {\n // Hash(current computed hash + current element of the proof)\n computedHash = keccak256(abi.encodePacked(computedHash, proofElement));\n } else {\n // Hash(current element of the proof + current computed hash)\n computedHash = keccak256(abi.encodePacked(proofElement, computedHash));\n }\n }\n return computedHash;\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.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 ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/utils/introspection/IERC165.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 IERC165 {\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" + }, + "@openzeppelin/contracts-0.8/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/utils/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@openzeppelin/contracts-0.8/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (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\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" + }, + "@openzeppelin/contracts-0.8/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n __Context_init_unchained();\n __ERC165_init_unchained();\n __AccessControl_init_unchained();\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role, _msgSender());\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Context_init_unchained();\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/metatx/ERC2771ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (metatx/ERC2771Context.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Context variant with ERC2771 support.\n */\nabstract contract ERC2771ContextUpgradeable is Initializable, ContextUpgradeable {\n address private _trustedForwarder;\n\n function __ERC2771Context_init(address trustedForwarder) internal onlyInitializing {\n __Context_init_unchained();\n __ERC2771Context_init_unchained(trustedForwarder);\n }\n\n function __ERC2771Context_init_unchained(address trustedForwarder) internal onlyInitializing {\n _trustedForwarder = trustedForwarder;\n }\n\n function isTrustedForwarder(address forwarder) public view virtual returns (bool) {\n return forwarder == _trustedForwarder;\n }\n\n function _msgSender() internal view virtual override returns (address sender) {\n if (isTrustedForwarder(msg.sender)) {\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n return super._msgSender();\n }\n }\n\n function _msgData() internal view virtual override returns (bytes calldata) {\n if (isTrustedForwarder(msg.sender)) {\n return msg.data[:msg.data.length - 20];\n } else {\n return super._msgData();\n }\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\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 a proxied contract can't have 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 * 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 initialize the implementation contract, you can either invoke the\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() initializer {}\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool 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 Modifier to protect an initializer function from being invoked twice.\n */\n modifier initializer() {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\n // contract may have been reentered.\n require(_initializing ? _isConstructor() : !_initialized, \"Initializable: contract is already initialized\");\n\n bool isTopLevelCall = !_initializing;\n if (isTopLevelCall) {\n _initializing = true;\n _initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n _initializing = false;\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} modifier, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Context_init_unchained();\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n require(!paused(), \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n require(paused(), \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (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 __Context_init_unchained();\n __ERC165_init_unchained();\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: balance query for the zero address\");\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: owner query for nonexistent token\");\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 require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\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 overriden 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 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 require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\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: transfer caller is not 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: transfer caller is not 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 require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, 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\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\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 of token that is not own\");\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\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits a {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 a {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 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 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 uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"./IERC721EnumerableUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\n * enumerability of all the token ids in the contract as well as all token ids owned by each\n * account.\n */\nabstract contract ERC721EnumerableUpgradeable is Initializable, ERC721Upgradeable, IERC721EnumerableUpgradeable {\n function __ERC721Enumerable_init() internal onlyInitializing {\n __Context_init_unchained();\n __ERC165_init_unchained();\n __ERC721Enumerable_init_unchained();\n }\n\n function __ERC721Enumerable_init_unchained() internal onlyInitializing {\n }\n // Mapping from owner to list of owned token IDs\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\n\n // Mapping from token ID to index of the owner tokens list\n mapping(uint256 => uint256) private _ownedTokensIndex;\n\n // Array with all token ids, used for enumeration\n uint256[] private _allTokens;\n\n // Mapping from token id to position in the allTokens array\n mapping(uint256 => uint256) private _allTokensIndex;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC721Upgradeable) returns (bool) {\n return interfaceId == type(IERC721EnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721Upgradeable.balanceOf(owner), \"ERC721Enumerable: owner index out of bounds\");\n return _ownedTokens[owner][index];\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _allTokens.length;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721EnumerableUpgradeable.totalSupply(), \"ERC721Enumerable: global index out of bounds\");\n return _allTokens[index];\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` cannot be the zero address.\n * - `to` cannot be the zero address.\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 override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n if (from == address(0)) {\n _addTokenToAllTokensEnumeration(tokenId);\n } else if (from != to) {\n _removeTokenFromOwnerEnumeration(from, tokenId);\n }\n if (to == address(0)) {\n _removeTokenFromAllTokensEnumeration(tokenId);\n } else if (to != from) {\n _addTokenToOwnerEnumeration(to, tokenId);\n }\n }\n\n /**\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\n * @param to address representing the new owner of the given token ID\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\n */\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\n uint256 length = ERC721Upgradeable.balanceOf(to);\n _ownedTokens[to][length] = tokenId;\n _ownedTokensIndex[tokenId] = length;\n }\n\n /**\n * @dev Private function to add a token to this extension's token tracking data structures.\n * @param tokenId uint256 ID of the token to be added to the tokens list\n */\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\n _allTokensIndex[tokenId] = _allTokens.length;\n _allTokens.push(tokenId);\n }\n\n /**\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\n * @param from address representing the previous owner of the given token ID\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\n */\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = ERC721Upgradeable.balanceOf(from) - 1;\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary\n if (tokenIndex != lastTokenIndex) {\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\n\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n }\n\n // This also deletes the contents at the last position of the array\n delete _ownedTokensIndex[tokenId];\n delete _ownedTokens[from][lastTokenIndex];\n }\n\n /**\n * @dev Private function to remove a token from this extension's token tracking data structures.\n * This has O(1) time complexity, but alters the order of the _allTokens array.\n * @param tokenId uint256 ID of the token to be removed from the tokens list\n */\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = _allTokens.length - 1;\n uint256 tokenIndex = _allTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\n uint256 lastTokenId = _allTokens[lastTokenIndex];\n\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n\n // This also deletes the contents at the last position of the array\n delete _allTokensIndex[tokenId];\n _allTokens.pop();\n }\n uint256[46] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721EnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721EnumerableUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\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/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (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 `IERC721.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/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (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`, 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 be 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 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 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 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 /**\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" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\n\npragma solidity ^0.8.0;\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 function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 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\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/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 __Context_init_unchained();\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 uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s;\n uint8 v;\n assembly {\n s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\n v := add(shr(255, vs), 27)\n }\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\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 __ERC165_init_unchained();\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 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" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (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\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" + }, + "fx-portal/contracts/lib/ExitPayloadReader.sol": { + "content": "pragma solidity ^0.8.0;\n\nimport { RLPReader } from \"./RLPReader.sol\";\n\nlibrary ExitPayloadReader {\n using RLPReader for bytes;\n using RLPReader for RLPReader.RLPItem;\n\n uint8 constant WORD_SIZE = 32;\n\n struct ExitPayload {\n RLPReader.RLPItem[] data;\n }\n\n struct Receipt {\n RLPReader.RLPItem[] data;\n bytes raw;\n uint256 logIndex;\n }\n\n struct Log {\n RLPReader.RLPItem data;\n RLPReader.RLPItem[] list;\n }\n\n struct LogTopics {\n RLPReader.RLPItem[] data;\n }\n\n // copy paste of private copy() from RLPReader to avoid changing of existing contracts\n function copy(uint src, uint dest, uint len) private pure {\n if (len == 0) return;\n\n // copy as many word sizes as possible\n for (; len >= WORD_SIZE; len -= WORD_SIZE) {\n assembly {\n mstore(dest, mload(src))\n }\n\n src += WORD_SIZE;\n dest += WORD_SIZE;\n }\n\n // left over bytes. Mask is used to remove unwanted bytes from the word\n uint mask = 256 ** (WORD_SIZE - len) - 1;\n assembly {\n let srcpart := and(mload(src), not(mask)) // zero out src\n let destpart := and(mload(dest), mask) // retrieve the bytes\n mstore(dest, or(destpart, srcpart))\n }\n }\n\n function toExitPayload(bytes memory data)\n internal\n pure\n returns (ExitPayload memory)\n {\n RLPReader.RLPItem[] memory payloadData = data\n .toRlpItem()\n .toList();\n\n return ExitPayload(payloadData);\n }\n\n function getHeaderNumber(ExitPayload memory payload) internal pure returns(uint256) {\n return payload.data[0].toUint();\n }\n\n function getBlockProof(ExitPayload memory payload) internal pure returns(bytes memory) {\n return payload.data[1].toBytes();\n }\n\n function getBlockNumber(ExitPayload memory payload) internal pure returns(uint256) {\n return payload.data[2].toUint();\n }\n\n function getBlockTime(ExitPayload memory payload) internal pure returns(uint256) {\n return payload.data[3].toUint();\n }\n\n function getTxRoot(ExitPayload memory payload) internal pure returns(bytes32) {\n return bytes32(payload.data[4].toUint());\n }\n\n function getReceiptRoot(ExitPayload memory payload) internal pure returns(bytes32) {\n return bytes32(payload.data[5].toUint());\n }\n\n function getReceipt(ExitPayload memory payload) internal pure returns(Receipt memory receipt) {\n receipt.raw = payload.data[6].toBytes();\n RLPReader.RLPItem memory receiptItem = receipt.raw.toRlpItem();\n\n if (receiptItem.isList()) {\n // legacy tx\n receipt.data = receiptItem.toList();\n } else {\n // pop first byte before parsting receipt\n bytes memory typedBytes = receipt.raw;\n bytes memory result = new bytes(typedBytes.length - 1);\n uint256 srcPtr;\n uint256 destPtr;\n assembly {\n srcPtr := add(33, typedBytes)\n destPtr := add(0x20, result)\n }\n\n copy(srcPtr, destPtr, result.length);\n receipt.data = result.toRlpItem().toList();\n }\n\n receipt.logIndex = getReceiptLogIndex(payload);\n return receipt;\n }\n\n function getReceiptProof(ExitPayload memory payload) internal pure returns(bytes memory) {\n return payload.data[7].toBytes();\n }\n\n function getBranchMaskAsBytes(ExitPayload memory payload) internal pure returns(bytes memory) {\n return payload.data[8].toBytes();\n }\n\n function getBranchMaskAsUint(ExitPayload memory payload) internal pure returns(uint256) {\n return payload.data[8].toUint();\n }\n\n function getReceiptLogIndex(ExitPayload memory payload) internal pure returns(uint256) {\n return payload.data[9].toUint();\n }\n \n // Receipt methods\n function toBytes(Receipt memory receipt) internal pure returns(bytes memory) {\n return receipt.raw;\n }\n\n function getLog(Receipt memory receipt) internal pure returns(Log memory) {\n RLPReader.RLPItem memory logData = receipt.data[3].toList()[receipt.logIndex];\n return Log(logData, logData.toList());\n }\n\n // Log methods\n function getEmitter(Log memory log) internal pure returns(address) {\n return RLPReader.toAddress(log.list[0]);\n }\n\n function getTopics(Log memory log) internal pure returns(LogTopics memory) {\n return LogTopics(log.list[1].toList());\n }\n\n function getData(Log memory log) internal pure returns(bytes memory) {\n return log.list[2].toBytes();\n }\n\n function toRlpBytes(Log memory log) internal pure returns(bytes memory) {\n return log.data.toRlpBytes();\n }\n\n // LogTopics methods\n function getField(LogTopics memory topics, uint256 index) internal pure returns(RLPReader.RLPItem memory) {\n return topics.data[index];\n }\n}\n" + }, + "fx-portal/contracts/lib/Merkle.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nlibrary Merkle {\n function checkMembership(\n bytes32 leaf,\n uint256 index,\n bytes32 rootHash,\n bytes memory proof\n ) internal pure returns (bool) {\n require(proof.length % 32 == 0, \"Invalid proof length\");\n uint256 proofHeight = proof.length / 32;\n // Proof of size n means, height of the tree is n+1.\n // In a tree of height n+1, max #leafs possible is 2 ^ n\n require(index < 2 ** proofHeight, \"Leaf index is too big\");\n\n bytes32 proofElement;\n bytes32 computedHash = leaf;\n for (uint256 i = 32; i <= proof.length; i += 32) {\n assembly {\n proofElement := mload(add(proof, i))\n }\n\n if (index % 2 == 0) {\n computedHash = keccak256(\n abi.encodePacked(computedHash, proofElement)\n );\n } else {\n computedHash = keccak256(\n abi.encodePacked(proofElement, computedHash)\n );\n }\n\n index = index / 2;\n }\n return computedHash == rootHash;\n }\n}\n" + }, + "fx-portal/contracts/lib/MerklePatriciaProof.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {RLPReader} from \"./RLPReader.sol\";\n\nlibrary MerklePatriciaProof {\n /*\n * @dev Verifies a merkle patricia proof.\n * @param value The terminating value in the trie.\n * @param encodedPath The path in the trie leading to value.\n * @param rlpParentNodes The rlp encoded stack of nodes.\n * @param root The root hash of the trie.\n * @return The boolean validity of the proof.\n */\n function verify(\n bytes memory value,\n bytes memory encodedPath,\n bytes memory rlpParentNodes,\n bytes32 root\n ) internal pure returns (bool) {\n RLPReader.RLPItem memory item = RLPReader.toRlpItem(rlpParentNodes);\n RLPReader.RLPItem[] memory parentNodes = RLPReader.toList(item);\n\n bytes memory currentNode;\n RLPReader.RLPItem[] memory currentNodeList;\n\n bytes32 nodeKey = root;\n uint256 pathPtr = 0;\n\n bytes memory path = _getNibbleArray(encodedPath);\n if (path.length == 0) {\n return false;\n }\n\n for (uint256 i = 0; i < parentNodes.length; i++) {\n if (pathPtr > path.length) {\n return false;\n }\n\n currentNode = RLPReader.toRlpBytes(parentNodes[i]);\n if (nodeKey != keccak256(currentNode)) {\n return false;\n }\n currentNodeList = RLPReader.toList(parentNodes[i]);\n\n if (currentNodeList.length == 17) {\n if (pathPtr == path.length) {\n if (\n keccak256(RLPReader.toBytes(currentNodeList[16])) ==\n keccak256(value)\n ) {\n return true;\n } else {\n return false;\n }\n }\n\n uint8 nextPathNibble = uint8(path[pathPtr]);\n if (nextPathNibble > 16) {\n return false;\n }\n nodeKey = bytes32(\n RLPReader.toUintStrict(currentNodeList[nextPathNibble])\n );\n pathPtr += 1;\n } else if (currentNodeList.length == 2) {\n uint256 traversed = _nibblesToTraverse(\n RLPReader.toBytes(currentNodeList[0]),\n path,\n pathPtr\n );\n if (pathPtr + traversed == path.length) {\n //leaf node\n if (\n keccak256(RLPReader.toBytes(currentNodeList[1])) ==\n keccak256(value)\n ) {\n return true;\n } else {\n return false;\n }\n }\n\n //extension node\n if (traversed == 0) {\n return false;\n }\n\n pathPtr += traversed;\n nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[1]));\n } else {\n return false;\n }\n }\n }\n\n function _nibblesToTraverse(\n bytes memory encodedPartialPath,\n bytes memory path,\n uint256 pathPtr\n ) private pure returns (uint256) {\n uint256 len = 0;\n // encodedPartialPath has elements that are each two hex characters (1 byte), but partialPath\n // and slicedPath have elements that are each one hex character (1 nibble)\n bytes memory partialPath = _getNibbleArray(encodedPartialPath);\n bytes memory slicedPath = new bytes(partialPath.length);\n\n // pathPtr counts nibbles in path\n // partialPath.length is a number of nibbles\n for (uint256 i = pathPtr; i < pathPtr + partialPath.length; i++) {\n bytes1 pathNibble = path[i];\n slicedPath[i - pathPtr] = pathNibble;\n }\n\n if (keccak256(partialPath) == keccak256(slicedPath)) {\n len = partialPath.length;\n } else {\n len = 0;\n }\n return len;\n }\n\n // bytes b must be hp encoded\n function _getNibbleArray(bytes memory b)\n internal\n pure\n returns (bytes memory)\n {\n bytes memory nibbles = \"\";\n if (b.length > 0) {\n uint8 offset;\n uint8 hpNibble = uint8(_getNthNibbleOfBytes(0, b));\n if (hpNibble == 1 || hpNibble == 3) {\n nibbles = new bytes(b.length * 2 - 1);\n bytes1 oddNibble = _getNthNibbleOfBytes(1, b);\n nibbles[0] = oddNibble;\n offset = 1;\n } else {\n nibbles = new bytes(b.length * 2 - 2);\n offset = 0;\n }\n\n for (uint256 i = offset; i < nibbles.length; i++) {\n nibbles[i] = _getNthNibbleOfBytes(i - offset + 2, b);\n }\n }\n return nibbles;\n }\n\n function _getNthNibbleOfBytes(uint256 n, bytes memory str)\n private\n pure\n returns (bytes1)\n {\n return\n bytes1(\n n % 2 == 0 ? uint8(str[n / 2]) / 0x10 : uint8(str[n / 2]) % 0x10\n );\n }\n}" + }, + "fx-portal/contracts/lib/RLPReader.sol": { + "content": "/*\n* @author Hamdi Allam hamdi.allam97@gmail.com\n* Please reach out with any questions or concerns\n*/\npragma solidity ^0.8.0;\n\nlibrary RLPReader {\n uint8 constant STRING_SHORT_START = 0x80;\n uint8 constant STRING_LONG_START = 0xb8;\n uint8 constant LIST_SHORT_START = 0xc0;\n uint8 constant LIST_LONG_START = 0xf8;\n uint8 constant WORD_SIZE = 32;\n\n struct RLPItem {\n uint len;\n uint memPtr;\n }\n\n struct Iterator {\n RLPItem item; // Item that's being iterated over.\n uint nextPtr; // Position of the next item in the list.\n }\n\n /*\n * @dev Returns the next element in the iteration. Reverts if it has not next element.\n * @param self The iterator.\n * @return The next element in the iteration.\n */\n function next(Iterator memory self) internal pure returns (RLPItem memory) {\n require(hasNext(self));\n\n uint ptr = self.nextPtr;\n uint itemLength = _itemLength(ptr);\n self.nextPtr = ptr + itemLength;\n\n return RLPItem(itemLength, ptr);\n }\n\n /*\n * @dev Returns true if the iteration has more elements.\n * @param self The iterator.\n * @return true if the iteration has more elements.\n */\n function hasNext(Iterator memory self) internal pure returns (bool) {\n RLPItem memory item = self.item;\n return self.nextPtr < item.memPtr + item.len;\n }\n\n /*\n * @param item RLP encoded bytes\n */\n function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) {\n uint memPtr;\n assembly {\n memPtr := add(item, 0x20)\n }\n\n return RLPItem(item.length, memPtr);\n }\n\n /*\n * @dev Create an iterator. Reverts if item is not a list.\n * @param self The RLP item.\n * @return An 'Iterator' over the item.\n */\n function iterator(RLPItem memory self) internal pure returns (Iterator memory) {\n require(isList(self));\n\n uint ptr = self.memPtr + _payloadOffset(self.memPtr);\n return Iterator(self, ptr);\n }\n\n /*\n * @param item RLP encoded bytes\n */\n function rlpLen(RLPItem memory item) internal pure returns (uint) {\n return item.len;\n }\n\n /*\n * @param item RLP encoded bytes\n */\n function payloadLen(RLPItem memory item) internal pure returns (uint) {\n return item.len - _payloadOffset(item.memPtr);\n }\n\n /*\n * @param item RLP encoded list in bytes\n */\n function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) {\n require(isList(item));\n\n uint items = numItems(item);\n RLPItem[] memory result = new RLPItem[](items);\n\n uint memPtr = item.memPtr + _payloadOffset(item.memPtr);\n uint dataLen;\n for (uint i = 0; i < items; i++) {\n dataLen = _itemLength(memPtr);\n result[i] = RLPItem(dataLen, memPtr); \n memPtr = memPtr + dataLen;\n }\n\n return result;\n }\n\n // @return indicator whether encoded payload is a list. negate this function call for isData.\n function isList(RLPItem memory item) internal pure returns (bool) {\n if (item.len == 0) return false;\n\n uint8 byte0;\n uint memPtr = item.memPtr;\n assembly {\n byte0 := byte(0, mload(memPtr))\n }\n\n if (byte0 < LIST_SHORT_START)\n return false;\n return true;\n }\n\n /*\n * @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory.\n * @return keccak256 hash of RLP encoded bytes.\n */\n function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) {\n uint256 ptr = item.memPtr;\n uint256 len = item.len;\n bytes32 result;\n assembly {\n result := keccak256(ptr, len)\n }\n return result;\n }\n\n function payloadLocation(RLPItem memory item) internal pure returns (uint, uint) {\n uint offset = _payloadOffset(item.memPtr);\n uint memPtr = item.memPtr + offset;\n uint len = item.len - offset; // data length\n return (memPtr, len);\n }\n\n /*\n * @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory.\n * @return keccak256 hash of the item payload.\n */\n function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) {\n (uint memPtr, uint len) = payloadLocation(item);\n bytes32 result;\n assembly {\n result := keccak256(memPtr, len)\n }\n return result;\n }\n\n /** RLPItem conversions into data types **/\n\n // @returns raw rlp encoding in bytes\n function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) {\n bytes memory result = new bytes(item.len);\n if (result.length == 0) return result;\n \n uint ptr;\n assembly {\n ptr := add(0x20, result)\n }\n\n copy(item.memPtr, ptr, item.len);\n return result;\n }\n\n // any non-zero byte is considered true\n function toBoolean(RLPItem memory item) internal pure returns (bool) {\n require(item.len == 1);\n uint result;\n uint memPtr = item.memPtr;\n assembly {\n result := byte(0, mload(memPtr))\n }\n\n return result == 0 ? false : true;\n }\n\n function toAddress(RLPItem memory item) internal pure returns (address) {\n // 1 byte for the length prefix\n require(item.len == 21);\n\n return address(uint160(toUint(item)));\n }\n\n function toUint(RLPItem memory item) internal pure returns (uint) {\n require(item.len > 0 && item.len <= 33);\n\n uint offset = _payloadOffset(item.memPtr);\n uint len = item.len - offset;\n\n uint result;\n uint memPtr = item.memPtr + offset;\n assembly {\n result := mload(memPtr)\n\n // shfit to the correct location if neccesary\n if lt(len, 32) {\n result := div(result, exp(256, sub(32, len)))\n }\n }\n\n return result;\n }\n\n // enforces 32 byte length\n function toUintStrict(RLPItem memory item) internal pure returns (uint) {\n // one byte prefix\n require(item.len == 33);\n\n uint result;\n uint memPtr = item.memPtr + 1;\n assembly {\n result := mload(memPtr)\n }\n\n return result;\n }\n\n function toBytes(RLPItem memory item) internal pure returns (bytes memory) {\n require(item.len > 0);\n\n uint offset = _payloadOffset(item.memPtr);\n uint len = item.len - offset; // data length\n bytes memory result = new bytes(len);\n\n uint destPtr;\n assembly {\n destPtr := add(0x20, result)\n }\n\n copy(item.memPtr + offset, destPtr, len);\n return result;\n }\n\n /*\n * Private Helpers\n */\n\n // @return number of payload items inside an encoded list.\n function numItems(RLPItem memory item) private pure returns (uint) {\n if (item.len == 0) return 0;\n\n uint count = 0;\n uint currPtr = item.memPtr + _payloadOffset(item.memPtr);\n uint endPtr = item.memPtr + item.len;\n while (currPtr < endPtr) {\n currPtr = currPtr + _itemLength(currPtr); // skip over an item\n count++;\n }\n\n return count;\n }\n\n // @return entire rlp item byte length\n function _itemLength(uint memPtr) private pure returns (uint) {\n uint itemLen;\n uint byte0;\n assembly {\n byte0 := byte(0, mload(memPtr))\n }\n\n if (byte0 < STRING_SHORT_START)\n itemLen = 1;\n \n else if (byte0 < STRING_LONG_START)\n itemLen = byte0 - STRING_SHORT_START + 1;\n\n else if (byte0 < LIST_SHORT_START) {\n assembly {\n let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is\n memPtr := add(memPtr, 1) // skip over the first byte\n /* 32 byte word size */\n let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len\n itemLen := add(dataLen, add(byteLen, 1))\n }\n }\n\n else if (byte0 < LIST_LONG_START) {\n itemLen = byte0 - LIST_SHORT_START + 1;\n } \n\n else {\n assembly {\n let byteLen := sub(byte0, 0xf7)\n memPtr := add(memPtr, 1)\n\n let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length\n itemLen := add(dataLen, add(byteLen, 1))\n }\n }\n\n return itemLen;\n }\n\n // @return number of bytes until the data\n function _payloadOffset(uint memPtr) private pure returns (uint) {\n uint byte0;\n assembly {\n byte0 := byte(0, mload(memPtr))\n }\n\n if (byte0 < STRING_SHORT_START) \n return 0;\n else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START))\n return 1;\n else if (byte0 < LIST_SHORT_START) // being explicit\n return byte0 - (STRING_LONG_START - 1) + 1;\n else\n return byte0 - (LIST_LONG_START - 1) + 1;\n }\n\n /*\n * @param src Pointer to source\n * @param dest Pointer to destination\n * @param len Amount of memory to copy from the source\n */\n function copy(uint src, uint dest, uint len) private pure {\n if (len == 0) return;\n\n // copy as many word sizes as possible\n for (; len >= WORD_SIZE; len -= WORD_SIZE) {\n assembly {\n mstore(dest, mload(src))\n }\n\n src += WORD_SIZE;\n dest += WORD_SIZE;\n }\n\n if (len == 0) return;\n\n // left over bytes. Mask is used to remove unwanted bytes from the word\n uint mask = 256 ** (WORD_SIZE - len) - 1;\n\n assembly {\n let srcpart := and(mload(src), not(mask)) // zero out src\n let destpart := and(mload(dest), mask) // retrieve the bytes\n mstore(dest, or(destpart, srcpart))\n }\n }\n}\n" + }, + "fx-portal/contracts/tunnel/FxBaseChildTunnel.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n// IFxMessageProcessor represents interface to process message\ninterface IFxMessageProcessor {\n function processMessageFromRoot(uint256 stateId, address rootMessageSender, bytes calldata data) external;\n}\n\n/**\n* @notice Mock child tunnel contract to receive and send message from L2\n*/\nabstract contract FxBaseChildTunnel is IFxMessageProcessor{\n // MessageTunnel on L1 will get data from this event\n event MessageSent(bytes message);\n\n // fx child\n address public fxChild;\n\n // fx root tunnel\n address public fxRootTunnel;\n\n constructor(address _fxChild) {\n fxChild = _fxChild;\n }\n\n // Sender must be fxRootTunnel in case of ERC20 tunnel\n modifier validateSender(address sender) {\n require(sender == fxRootTunnel, \"FxBaseChildTunnel: INVALID_SENDER_FROM_ROOT\");\n _;\n }\n\n // set fxRootTunnel if not set already\n function setFxRootTunnel(address _fxRootTunnel) external {\n require(fxRootTunnel == address(0x0), \"FxBaseChildTunnel: ROOT_TUNNEL_ALREADY_SET\");\n fxRootTunnel = _fxRootTunnel;\n }\n\n function processMessageFromRoot(uint256 stateId, address rootMessageSender, bytes calldata data) external override {\n require(msg.sender == fxChild, \"FxBaseChildTunnel: INVALID_SENDER\");\n _processMessageFromRoot(stateId, rootMessageSender, data);\n }\n\n /**\n * @notice Emit message that can be received on Root Tunnel\n * @dev Call the internal function when need to emit message\n * @param message bytes message that will be sent to Root Tunnel\n * some message examples -\n * abi.encode(tokenId);\n * abi.encode(tokenId, tokenMetadata);\n * abi.encode(messageType, messageData);\n */\n function _sendMessageToRoot(bytes memory message) internal {\n emit MessageSent(message);\n }\n\n /**\n * @notice Process message received from Root Tunnel\n * @dev function needs to be implemented to handle message as per requirement\n * This is called by onStateReceive function.\n * Since it is called via a system call, any event will not be emitted during its execution.\n * @param stateId unique state id\n * @param sender root message sender\n * @param message bytes message that was sent from Root Tunnel\n */\n function _processMessageFromRoot(uint256 stateId, address sender, bytes memory message) virtual internal;\n}\n" + }, + "fx-portal/contracts/tunnel/FxBaseRootTunnel.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n\nimport {RLPReader} from \"../lib/RLPReader.sol\";\nimport {MerklePatriciaProof} from \"../lib/MerklePatriciaProof.sol\";\nimport {Merkle} from \"../lib/Merkle.sol\";\nimport \"../lib/ExitPayloadReader.sol\";\n\n\ninterface IFxStateSender {\n function sendMessageToChild(address _receiver, bytes calldata _data) external;\n}\n\ncontract ICheckpointManager {\n struct HeaderBlock {\n bytes32 root;\n uint256 start;\n uint256 end;\n uint256 createdAt;\n address proposer;\n }\n\n /**\n * @notice mapping of checkpoint header numbers to block details\n * @dev These checkpoints are submited by plasma contracts\n */\n mapping(uint256 => HeaderBlock) public headerBlocks;\n}\n\nabstract contract FxBaseRootTunnel {\n using RLPReader for RLPReader.RLPItem;\n using Merkle for bytes32;\n using ExitPayloadReader for bytes;\n using ExitPayloadReader for ExitPayloadReader.ExitPayload;\n using ExitPayloadReader for ExitPayloadReader.Log;\n using ExitPayloadReader for ExitPayloadReader.LogTopics;\n using ExitPayloadReader for ExitPayloadReader.Receipt;\n\n // keccak256(MessageSent(bytes))\n bytes32 public constant SEND_MESSAGE_EVENT_SIG = 0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036;\n\n // state sender contract\n IFxStateSender public fxRoot;\n // root chain manager\n ICheckpointManager public checkpointManager;\n // child tunnel contract which receives and sends messages \n address public fxChildTunnel;\n\n // storage to avoid duplicate exits\n mapping(bytes32 => bool) public processedExits;\n\n constructor(address _checkpointManager, address _fxRoot) {\n checkpointManager = ICheckpointManager(_checkpointManager);\n fxRoot = IFxStateSender(_fxRoot);\n }\n\n // set fxChildTunnel if not set already\n function setFxChildTunnel(address _fxChildTunnel) public {\n require(fxChildTunnel == address(0x0), \"FxBaseRootTunnel: CHILD_TUNNEL_ALREADY_SET\");\n fxChildTunnel = _fxChildTunnel;\n }\n\n /**\n * @notice Send bytes message to Child Tunnel\n * @param message bytes message that will be sent to Child Tunnel\n * some message examples -\n * abi.encode(tokenId);\n * abi.encode(tokenId, tokenMetadata);\n * abi.encode(messageType, messageData);\n */\n function _sendMessageToChild(bytes memory message) internal {\n fxRoot.sendMessageToChild(fxChildTunnel, message);\n }\n\n function _validateAndExtractMessage(bytes memory inputData) internal returns (bytes memory) {\n ExitPayloadReader.ExitPayload memory payload = inputData.toExitPayload();\n\n bytes memory branchMaskBytes = payload.getBranchMaskAsBytes();\n uint256 blockNumber = payload.getBlockNumber();\n // checking if exit has already been processed\n // unique exit is identified using hash of (blockNumber, branchMask, receiptLogIndex)\n bytes32 exitHash = keccak256(\n abi.encodePacked(\n blockNumber,\n // first 2 nibbles are dropped while generating nibble array\n // this allows branch masks that are valid but bypass exitHash check (changing first 2 nibbles only)\n // so converting to nibble array and then hashing it\n MerklePatriciaProof._getNibbleArray(branchMaskBytes),\n payload.getReceiptLogIndex()\n )\n );\n require(\n processedExits[exitHash] == false,\n \"FxRootTunnel: EXIT_ALREADY_PROCESSED\"\n );\n processedExits[exitHash] = true;\n\n ExitPayloadReader.Receipt memory receipt = payload.getReceipt();\n ExitPayloadReader.Log memory log = receipt.getLog();\n\n // check child tunnel\n require(fxChildTunnel == log.getEmitter(), \"FxRootTunnel: INVALID_FX_CHILD_TUNNEL\");\n\n bytes32 receiptRoot = payload.getReceiptRoot();\n // verify receipt inclusion\n require(\n MerklePatriciaProof.verify(\n receipt.toBytes(), \n branchMaskBytes, \n payload.getReceiptProof(), \n receiptRoot\n ),\n \"FxRootTunnel: INVALID_RECEIPT_PROOF\"\n );\n\n // verify checkpoint inclusion\n _checkBlockMembershipInCheckpoint(\n blockNumber,\n payload.getBlockTime(),\n payload.getTxRoot(),\n receiptRoot,\n payload.getHeaderNumber(),\n payload.getBlockProof()\n );\n\n ExitPayloadReader.LogTopics memory topics = log.getTopics();\n\n require(\n bytes32(topics.getField(0).toUint()) == SEND_MESSAGE_EVENT_SIG, // topic0 is event sig\n \"FxRootTunnel: INVALID_SIGNATURE\"\n );\n\n // received message data\n (bytes memory message) = abi.decode(log.getData(), (bytes)); // event decodes params again, so decoding bytes to get message\n return message;\n }\n\n function _checkBlockMembershipInCheckpoint(\n uint256 blockNumber,\n uint256 blockTime,\n bytes32 txRoot,\n bytes32 receiptRoot,\n uint256 headerNumber,\n bytes memory blockProof\n ) private view returns (uint256) {\n (\n bytes32 headerRoot,\n uint256 startBlock,\n ,\n uint256 createdAt,\n\n ) = checkpointManager.headerBlocks(headerNumber);\n\n require(\n keccak256(\n abi.encodePacked(blockNumber, blockTime, txRoot, receiptRoot)\n )\n .checkMembership(\n blockNumber-startBlock,\n headerRoot,\n blockProof\n ),\n \"FxRootTunnel: INVALID_HEADER\"\n );\n return createdAt;\n }\n\n /**\n * @notice receive message from L2 to L1, validated by proof\n * @dev This function verifies if the transaction actually happened on child chain\n *\n * @param inputData RLP encoded data of the reference tx containing following list of fields\n * 0 - headerNumber - Checkpoint header block number containing the reference tx\n * 1 - blockProof - Proof that the block header (in the child chain) is a leaf in the submitted merkle root\n * 2 - blockNumber - Block number containing the reference tx on child chain\n * 3 - blockTime - Reference tx block time\n * 4 - txRoot - Transactions root of block\n * 5 - receiptRoot - Receipts root of block\n * 6 - receipt - Receipt of the reference transaction\n * 7 - receiptProof - Merkle proof of the reference receipt\n * 8 - branchMask - 32 bits denoting the path of receipt in merkle tree\n * 9 - receiptLogIndex - Log Index to read from the receipt\n */\n function receiveMessage(bytes memory inputData) public virtual {\n bytes memory message = _validateAndExtractMessage(inputData);\n _processMessageFromChild(message);\n }\n\n /**\n * @notice Process message received from Child Tunnel\n * @dev function needs to be implemented to handle message as per requirement\n * This is called by onStateReceive function.\n * Since it is called via a system call, any event will not be emitted during its execution.\n * @param message bytes message that was sent from Child Tunnel\n */\n function _processMessageFromChild(bytes memory message) virtual internal;\n}\n" + }, + "src/solc_0.8/asset/AssetSignedAuctionWithAuth.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport {IERC20} from \"@openzeppelin/contracts-0.8/token/ERC20/IERC20.sol\";\nimport {Address} from \"@openzeppelin/contracts-0.8/utils/Address.sol\";\nimport {ReentrancyGuard} from \"@openzeppelin/contracts-0.8/security/ReentrancyGuard.sol\";\nimport {SigUtil} from \"../common/Libraries/SigUtil.sol\";\nimport {PriceUtil} from \"../common/Libraries/PriceUtil.sol\";\nimport {TheSandbox712} from \"../common/Base/TheSandbox712.sol\";\nimport {MetaTransactionReceiver} from \"../common/BaseWithStorage/MetaTransactionReceiver.sol\";\nimport {ERC1271} from \"../common/interfaces/ERC1271.sol\";\nimport {ERC1271Constants} from \"../common/interfaces/ERC1271Constants.sol\";\nimport {ERC1654} from \"../common/interfaces/ERC1654.sol\";\nimport {ERC1654Constants} from \"../common/interfaces/ERC1654Constants.sol\";\nimport {IAuthValidator} from \"../common/interfaces/IAuthValidator.sol\";\nimport {IERC1155} from \"../common/interfaces/IERC1155.sol\";\n\ncontract AssetSignedAuctionWithAuth is\n ReentrancyGuard,\n ERC1654Constants,\n ERC1271Constants,\n TheSandbox712,\n MetaTransactionReceiver\n{\n struct ClaimSellerOfferRequest {\n address buyer;\n address payable seller;\n address token;\n uint256[] purchase;\n uint256[] auctionData;\n uint256[] ids;\n uint256[] amounts;\n bytes signature;\n bytes backendSignature;\n }\n\n enum SignatureType {DIRECT, EIP1654, EIP1271}\n\n bytes32 public constant BACKEND_TYPEHASH =\n keccak256(\n \"Auction(address to,address from,address token,bytes auctionData,bytes ids,bytes amounts,bytes purchase)\"\n );\n\n bytes32 public constant AUCTION_TYPEHASH =\n keccak256(\"Auction(address from,address token,bytes auctionData,bytes ids,bytes amounts)\");\n\n event OfferClaimed(\n address indexed seller,\n address indexed buyer,\n uint256 indexed offerId,\n uint256 amount,\n uint256 pricePaid,\n uint256 feePaid\n );\n event OfferCancelled(address indexed seller, uint256 indexed offerId);\n event NewFeeLimit(uint256 feeLimit);\n\n uint256 public constant MAX_UINT256 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\n\n // Stack too deep, grouping parameters\n // AuctionData:\n uint256 public constant AuctionData_OfferId = 0;\n uint256 public constant AuctionData_StartingPrice = 1;\n uint256 public constant AuctionData_EndingPrice = 2;\n uint256 public constant AuctionData_StartedAt = 3;\n uint256 public constant AuctionData_Duration = 4;\n uint256 public constant AuctionData_Packs = 5;\n\n mapping(address => mapping(uint256 => uint256)) public claimed;\n\n IAuthValidator public _authValidator;\n IERC1155 public _asset;\n uint256 public _fee10000th = 0;\n uint256 public _feeLimit = 500;\n uint256 public _maxfeeLimit = 500; // 5%\n address payable public _feeCollector;\n\n event FeeSetup(address feeCollector, uint256 fee10000th);\n\n constructor(\n IERC1155 asset,\n address admin,\n address initialMetaTx,\n address payable feeCollector,\n uint256 fee10000th,\n address authValidator\n ) TheSandbox712() {\n require(fee10000th <= _feeLimit, \"Fee above the limit\");\n _asset = asset;\n _feeCollector = feeCollector;\n _fee10000th = fee10000th;\n emit FeeSetup(feeCollector, fee10000th);\n _admin = admin;\n _setMetaTransactionProcessor(initialMetaTx, true);\n _authValidator = IAuthValidator(authValidator);\n }\n\n // check backend signature to avoid front-running\n modifier isAuthValid(bytes memory signature, bytes32 hashedData) {\n require(_authValidator.isAuthValid(signature, hashedData), \"INVALID_AUTH\");\n _;\n }\n\n /// @notice set fee parameters\n /// @param feeCollector address receiving the fee\n /// @param fee10000th fee in 10,000th\n function setFee(address payable feeCollector, uint256 fee10000th) external {\n require(feeCollector != address(0), \"feeCollector cannot be Zero address\");\n require(msg.sender == _admin, \"only admin can change fee\");\n require(fee10000th <= _feeLimit, \"Fee above the limit\");\n _feeCollector = feeCollector;\n _fee10000th = fee10000th;\n emit FeeSetup(feeCollector, fee10000th);\n }\n\n /// @notice setFeeLimit parameters\n /// @param newFeeLimit new fee limit\n function setFeeLimit(uint256 newFeeLimit) external {\n require(msg.sender == _admin, \"only admin can change fee limit\");\n require(newFeeLimit <= _maxfeeLimit, \"new limit above max limit\");\n\n _feeLimit = newFeeLimit;\n\n emit NewFeeLimit(newFeeLimit);\n }\n\n /// @notice claim offer using EIP712\n /// @param input Claim Seller Offer Request\n function claimSellerOffer(ClaimSellerOfferRequest memory input)\n external\n payable\n isAuthValid(\n input.backendSignature,\n _hashBackendSig(\n input.buyer,\n input.seller,\n input.token,\n input.auctionData,\n input.ids,\n input.amounts,\n input.purchase\n )\n )\n {\n _verifyParameters(\n input.buyer,\n input.seller,\n input.token,\n input.purchase[0],\n input.auctionData,\n input.ids,\n input.amounts\n );\n _ensureCorrectSigner(\n input.seller,\n input.token,\n input.auctionData,\n input.ids,\n input.amounts,\n input.signature,\n SignatureType.DIRECT\n );\n _executeDeal(\n input.token,\n input.purchase,\n input.buyer,\n input.seller,\n input.auctionData,\n input.ids,\n input.amounts\n );\n }\n\n /// @notice claim offer using EIP712 and EIP1271 signature verification scheme\n /// @param input Claim Seller Offer Request\n function claimSellerOfferViaEIP1271(ClaimSellerOfferRequest memory input)\n external\n payable\n isAuthValid(\n input.backendSignature,\n _hashBackendSig(\n input.buyer,\n input.seller,\n input.token,\n input.auctionData,\n input.ids,\n input.amounts,\n input.purchase\n )\n )\n {\n _verifyParameters(\n input.buyer,\n input.seller,\n input.token,\n input.purchase[0],\n input.auctionData,\n input.ids,\n input.amounts\n );\n _ensureCorrectSigner(\n input.seller,\n input.token,\n input.auctionData,\n input.ids,\n input.amounts,\n input.signature,\n SignatureType.EIP1271\n );\n _executeDeal(\n input.token,\n input.purchase,\n input.buyer,\n input.seller,\n input.auctionData,\n input.ids,\n input.amounts\n );\n }\n\n /// @notice claim offer using EIP712 and EIP1654 signature verification scheme\n /// @param input Claim Seller Offer Request\n function claimSellerOfferViaEIP1654(ClaimSellerOfferRequest memory input)\n external\n payable\n isAuthValid(\n input.backendSignature,\n _hashBackendSig(\n input.buyer,\n input.seller,\n input.token,\n input.auctionData,\n input.ids,\n input.amounts,\n input.purchase\n )\n )\n {\n _verifyParameters(\n input.buyer,\n input.seller,\n input.token,\n input.purchase[0],\n input.auctionData,\n input.ids,\n input.amounts\n );\n _ensureCorrectSigner(\n input.seller,\n input.token,\n input.auctionData,\n input.ids,\n input.amounts,\n input.signature,\n SignatureType.EIP1654\n );\n _executeDeal(\n input.token,\n input.purchase,\n input.buyer,\n input.seller,\n input.auctionData,\n input.ids,\n input.amounts\n );\n }\n\n /// @notice cancel a offer previously signed, new offer need to use a id not used yet\n /// @param offerId offer to cancel\n function cancelSellerOffer(uint256 offerId) external {\n require(claimed[msg.sender][offerId] != MAX_UINT256, \"Sell offer was already cancelled\");\n claimed[msg.sender][offerId] = MAX_UINT256;\n emit OfferCancelled(msg.sender, offerId);\n }\n\n function _executeDeal(\n address token,\n uint256[] memory purchase,\n address buyer,\n address payable seller,\n uint256[] memory auctionData,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal nonReentrant {\n uint256 offer =\n PriceUtil.calculateCurrentPrice(\n auctionData[AuctionData_StartingPrice],\n auctionData[AuctionData_EndingPrice],\n auctionData[AuctionData_Duration],\n block.timestamp - auctionData[AuctionData_StartedAt]\n ) * purchase[0];\n claimed[seller][auctionData[AuctionData_OfferId]] =\n claimed[seller][auctionData[AuctionData_OfferId]] +\n purchase[0];\n\n uint256 fee = 0;\n if (_fee10000th > 0) {\n fee = PriceUtil.calculateFee(offer, _fee10000th);\n }\n\n uint256 total = offer + fee;\n require(total <= purchase[1], \"offer exceeds max amount to spend\");\n\n if (token != address(0)) {\n require(IERC20(token).transferFrom(buyer, seller, offer), \"failed to transfer token price\");\n if (fee > 0) {\n require(IERC20(token).transferFrom(buyer, _feeCollector, fee), \"failed to collect fee\");\n }\n } else {\n require(msg.value >= total, \"ETH < total\");\n if (msg.value > total) {\n Address.sendValue(payable(msg.sender), msg.value - total);\n }\n Address.sendValue(seller, offer);\n if (fee > 0) {\n Address.sendValue(_feeCollector, fee);\n }\n }\n\n uint256[] memory packAmounts = new uint256[](amounts.length);\n for (uint256 i = 0; i < packAmounts.length; i++) {\n packAmounts[i] = amounts[i] * purchase[0];\n }\n _asset.safeBatchTransferFrom(seller, buyer, ids, packAmounts, \"\");\n emit OfferClaimed(seller, buyer, auctionData[AuctionData_OfferId], purchase[0], offer, fee);\n }\n\n function _ensureCorrectSigner(\n address from,\n address token,\n uint256[] memory auctionData,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory signature,\n SignatureType signatureType\n ) internal view {\n bytes memory dataToHash;\n\n dataToHash = abi.encodePacked(\n \"\\x19\\x01\",\n _DOMAIN_SEPARATOR,\n _hashAuction(from, token, auctionData, ids, amounts)\n );\n\n if (signatureType == SignatureType.EIP1271) {\n require(\n ERC1271(from).isValidSignature(dataToHash, signature) == ERC1271_MAGICVALUE,\n \"invalid 1271 signature\"\n );\n } else if (signatureType == SignatureType.EIP1654) {\n require(\n ERC1654(from).isValidSignature(keccak256(dataToHash), signature) == ERC1654_MAGICVALUE,\n \"invalid 1654 signature\"\n );\n } else {\n address signer = SigUtil.recover(keccak256(dataToHash), signature);\n require(signer == from, \"signer != from\");\n }\n }\n\n function _verifyParameters(\n address buyer,\n address payable seller,\n address token,\n uint256 buyAmount,\n uint256[] memory auctionData,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal view {\n require(ids.length == amounts.length, \"ids and amounts length not matching\");\n require(\n buyer == msg.sender || (token != address(0) && _metaTransactionContracts[msg.sender]),\n \"not authorized\"\n );\n uint256 amountAlreadyClaimed = claimed[seller][auctionData[AuctionData_OfferId]];\n require(amountAlreadyClaimed != MAX_UINT256, \"Auction cancelled\");\n\n uint256 total = amountAlreadyClaimed + buyAmount;\n require(total <= auctionData[AuctionData_Packs], \"Buy amount exceeds sell amount\");\n\n require(auctionData[AuctionData_StartedAt] <= block.timestamp, \"Auction didn't start yet\");\n require(\n auctionData[AuctionData_StartedAt] + auctionData[AuctionData_Duration] > block.timestamp,\n \"Auction finished\"\n );\n }\n\n function _hashAuction(\n address from,\n address token,\n uint256[] memory auctionData,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal pure returns (bytes32) {\n return\n keccak256(\n abi.encode(\n AUCTION_TYPEHASH,\n from,\n token,\n keccak256(abi.encodePacked(auctionData)),\n keccak256(abi.encodePacked(ids)),\n keccak256(abi.encodePacked(amounts))\n )\n );\n }\n\n function _hashBackendSig(\n address to,\n address from,\n address token,\n uint256[] memory auctionData,\n uint256[] memory ids,\n uint256[] memory amounts,\n uint256[] memory purchase\n ) internal pure returns (bytes32) {\n return\n keccak256(\n abi.encode(\n BACKEND_TYPEHASH,\n to,\n from,\n token,\n keccak256(abi.encodePacked(auctionData)),\n keccak256(abi.encodePacked(ids)),\n keccak256(abi.encodePacked(amounts)),\n keccak256(abi.encodePacked(purchase))\n )\n );\n }\n}\n" + }, + "src/solc_0.8/asset/libraries/AssetHelper.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"../../common/interfaces/IAssetAttributesRegistry.sol\";\n\n// used to reduce PolygonAssetV2 contract code size\nlibrary AssetHelper {\n struct AssetRegistryData {\n IAssetAttributesRegistry assetRegistry;\n }\n\n function setCatalystDatas(\n AssetRegistryData storage self,\n IAssetAttributesRegistry.AssetGemsCatalystData[] memory assetGemsCatalystData\n ) public {\n for (uint256 i = 0; i < assetGemsCatalystData.length; i++) {\n require(assetGemsCatalystData[i].catalystContractId > 0, \"WRONG_catalystContractId\");\n require(assetGemsCatalystData[i].assetId != 0, \"WRONG_assetId\");\n self.assetRegistry.setCatalystWhenDepositOnOtherLayer(\n assetGemsCatalystData[i].assetId,\n assetGemsCatalystData[i].catalystContractId,\n assetGemsCatalystData[i].gemContractIds\n );\n }\n }\n\n function decodeAndSetCatalystDataL1toL2(AssetRegistryData storage self, bytes calldata depositData)\n public\n returns (\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes32[] memory hashes\n )\n {\n bytes memory data;\n IAssetAttributesRegistry.AssetGemsCatalystData[] memory catalystDatas;\n (ids, amounts, data) = abi.decode(depositData, (uint256[], uint256[], bytes));\n (hashes, catalystDatas) = abi.decode(data, (bytes32[], IAssetAttributesRegistry.AssetGemsCatalystData[]));\n\n setCatalystDatas(self, catalystDatas);\n }\n\n function decodeAndSetCatalystDataL2toL1(AssetRegistryData storage self, bytes calldata data)\n public\n returns (bytes32[] memory hashes)\n {\n IAssetAttributesRegistry.AssetGemsCatalystData[] memory catalystDatas;\n\n (hashes, catalystDatas) = abi.decode(data, (bytes32[], IAssetAttributesRegistry.AssetGemsCatalystData[]));\n\n setCatalystDatas(self, catalystDatas);\n }\n\n function getGemsAndCatalystData(AssetRegistryData storage self, uint256[] calldata assetIds)\n public\n view\n returns (IAssetAttributesRegistry.AssetGemsCatalystData[] memory)\n {\n uint256 count = getGemsCatalystDataCount(self, assetIds);\n uint256 indexInCatalystArray;\n\n IAssetAttributesRegistry.AssetGemsCatalystData[] memory gemsCatalystDatas =\n new IAssetAttributesRegistry.AssetGemsCatalystData[](count);\n\n for (uint256 i = 0; i < assetIds.length; i++) {\n (bool isDataFound, uint16 catalystId, uint16[] memory gemIds) = self.assetRegistry.getRecord(assetIds[i]);\n if (isDataFound) {\n IAssetAttributesRegistry.AssetGemsCatalystData memory data;\n data.assetId = assetIds[i];\n data.catalystContractId = catalystId;\n data.gemContractIds = gemIds;\n require(indexInCatalystArray < count, \"indexInCatalystArray out of bound\");\n gemsCatalystDatas[indexInCatalystArray] = data;\n indexInCatalystArray++;\n }\n }\n\n return gemsCatalystDatas;\n }\n\n function getGemsCatalystDataCount(AssetRegistryData storage self, uint256[] calldata assetIds)\n internal\n view\n returns (uint256)\n {\n uint256 count;\n\n for (uint256 i = 0; i < assetIds.length; i++) {\n (bool isDataFound, , ) = self.assetRegistry.getRecord(assetIds[i]);\n if (isDataFound) {\n count++;\n }\n }\n return count;\n }\n}\n" + }, + "src/solc_0.8/asset/libraries/ERC1155ERC721Helper.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nlibrary ERC1155ERC721Helper {\n bytes32 private constant base32Alphabet = 0x6162636465666768696A6B6C6D6E6F707172737475767778797A323334353637;\n\n uint256 public constant CREATOR_OFFSET_MULTIPLIER = uint256(2)**(256 - 160);\n uint256 public constant IS_NFT_OFFSET_MULTIPLIER = uint256(2)**(256 - 160 - 1);\n uint256 public constant CHAIN_INDEX_OFFSET_MULTIPLIER = uint256(2)**(256 - 160 - 1 - 8);\n uint256 public constant PACK_ID_OFFSET_MULTIPLIER = uint256(2)**(256 - 160 - 1 - 32 - 40);\n uint256 public constant PACK_NUM_FT_TYPES_OFFSET_MULTIPLIER = uint256(2)**(256 - 160 - 1 - 32 - 40 - 12);\n uint256 public constant NFT_INDEX_OFFSET = 63;\n\n uint256 public constant IS_NFT = 0x0000000000000000000000000000000000000000800000000000000000000000;\n uint256 public constant NOT_IS_NFT = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFF;\n uint256 public constant NFT_INDEX = 0x0000000000000000000000000000000000000000007FFFFF8000000000000000;\n uint256 public constant NOT_NFT_INDEX = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8000007FFFFFFFFFFFFFFF;\n uint256 public constant URI_ID = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000007FFFFFFFFFFFF800;\n uint256 public constant PACK_ID = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000007FFFFFFFFF800000;\n uint256 public constant PACK_INDEX = 0x00000000000000000000000000000000000000000000000000000000000007FF;\n uint256 public constant PACK_NUM_FT_TYPES = 0x00000000000000000000000000000000000000000000000000000000007FF800;\n uint256 public constant CHAIN_INDEX = 0x00000000000000000000000000000000000000007F8000000000000000000000;\n uint256 public constant NOT_CHAIN_INDEX = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF807FFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant MAX_SUPPLY = uint256(2)**32 - 1;\n uint256 public constant MAX_PACK_SIZE = uint256(2)**11;\n uint256 public constant MAX_NUM_FT = uint256(2)**12;\n\n function toFullURI(bytes32 hash, uint256 id) external pure returns (string memory) {\n return string(abi.encodePacked(\"ipfs://bafybei\", hash2base32(hash), \"/\", uint2str(id & PACK_INDEX), \".json\"));\n }\n\n // solium-disable-next-line security/no-assign-params\n function hash2base32(bytes32 hash) public pure returns (string memory _uintAsString) {\n uint256 _i = uint256(hash);\n uint256 k = 52;\n bytes memory bstr = new bytes(k);\n bstr[--k] = base32Alphabet[uint8((_i % 8) << 2)]; // uint8 s = uint8((256 - skip) % 5); // (_i % (2**s)) << (5-s)\n _i /= 8;\n while (k > 0) {\n bstr[--k] = base32Alphabet[_i % 32];\n _i /= 32;\n }\n return string(bstr);\n }\n\n // solium-disable-next-line security/no-assign-params\n function uint2str(uint256 _i) public pure returns (string memory _uintAsString) {\n if (_i == 0) {\n return \"0\";\n }\n\n uint256 j = _i;\n uint256 len;\n while (j != 0) {\n len++;\n j /= 10;\n }\n\n bytes memory bstr = new bytes(len);\n uint256 k = len;\n while (_i != 0) {\n bstr[--k] = bytes1(uint8(48 + uint8(_i % 10)));\n _i /= 10;\n }\n\n return string(bstr);\n }\n}\n" + }, + "src/solc_0.8/catalyst/interfaces/ICatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"../../common/interfaces/IAssetAttributesRegistry.sol\";\nimport \"../../common/interfaces/IAttributes.sol\";\nimport \"../../common/interfaces/IERC20Extended.sol\";\n\ninterface ICatalyst is IERC20Extended, IAttributes {\n function catalystId() external returns (uint16);\n\n function changeAttributes(IAttributes attributes) external;\n\n function getMaxGems() external view returns (uint8);\n\n function approveFor(\n address owner,\n address spender,\n uint256 amount\n ) external override returns (bool success);\n\n function getAttributes(uint256 assetId, IAssetAttributesRegistry.GemEvent[] calldata events)\n external\n view\n override\n returns (uint32[] memory values);\n\n function getDecimals() external pure returns (uint8);\n}\n" + }, + "src/solc_0.8/catalyst/interfaces/ICollectionCatalystMigrations.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\npragma experimental ABIEncoderV2;\n\ninterface ICollectionCatalystMigrations {\n struct Migration {\n uint256 assetId;\n uint16[] gemIds;\n uint64 blockNumber;\n }\n\n function batchMigrate(Migration[] calldata migrations) external;\n}\n" + }, + "src/solc_0.8/catalyst/interfaces/IGem.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"../../common/interfaces/IERC20Extended.sol\";\n\ninterface IGem is IERC20Extended {\n function gemId() external returns (uint16);\n\n function approveFor(\n address owner,\n address spender,\n uint256 amount\n ) external override returns (bool success);\n\n function getDecimals() external pure returns (uint8);\n}\n" + }, + "src/solc_0.8/catalyst/interfaces/IGemsCatalystsRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"../../common/interfaces/IAssetAttributesRegistry.sol\";\nimport \"./IGem.sol\";\nimport \"./ICatalyst.sol\";\n\ninterface IGemsCatalystsRegistry {\n function getAttributes(\n uint16 catalystId,\n uint256 assetId,\n IAssetAttributesRegistry.GemEvent[] calldata events\n ) external view returns (uint32[] memory values);\n\n function getMaxGems(uint16 catalystId) external view returns (uint8);\n\n function batchBurnGems(\n address from,\n uint16[] calldata gemIds,\n uint256[] calldata amounts\n ) external;\n\n function batchBurnCatalysts(\n address from,\n uint16[] calldata catalystIds,\n uint256[] calldata amounts\n ) external;\n\n function addGemsAndCatalysts(IGem[] calldata gems, ICatalyst[] calldata catalysts) external;\n\n function doesGemExist(uint16 gemId) external view returns (bool);\n\n function burnCatalyst(\n address from,\n uint16 catalystId,\n uint256 amount\n ) external;\n\n function burnGem(\n address from,\n uint16 gemId,\n uint256 amount\n ) external;\n\n function getCatalystDecimals(uint16 catalystId) external view returns (uint8);\n\n function getGemDecimals(uint16 gemId) external view returns (uint8);\n}\n" + }, + "src/solc_0.8/catalyst/interfaces/IOldCatalystRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\ninterface IOldCatalystRegistry {\n function getCatalyst(uint256 assetId) external view returns (bool exists, uint256 catalystId);\n}\n" + }, + "src/solc_0.8/claims/AssetGiveaway/AssetGiveaway.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/token/ERC1155/IERC1155.sol\";\nimport \"./ClaimERC1155.sol\";\nimport \"../../common/BaseWithStorage/WithAdmin.sol\";\n\n/// @title AssetGiveaway contract.\n/// @notice This contract manages ERC1155 claims.\ncontract AssetGiveaway is WithAdmin, ClaimERC1155 {\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n uint256 internal immutable _expiryTime;\n mapping(address => bool) public claimed;\n\n constructor(\n address asset,\n address admin,\n bytes32 merkleRoot,\n address assetsHolder,\n uint256 expiryTime\n ) ClaimERC1155(IERC1155(asset), assetsHolder) {\n _admin = admin;\n _merkleRoot = merkleRoot;\n _expiryTime = expiryTime;\n }\n\n /// @notice Function to set the merkle root hash for the asset data, if it is 0.\n /// @param merkleRoot The merkle root hash of the asset data.\n function setMerkleRoot(bytes32 merkleRoot) external onlyAdmin {\n require(_merkleRoot == 0, \"MERKLE_ROOT_ALREADY_SET\");\n _merkleRoot = merkleRoot;\n }\n\n /// @notice Function to permit the claiming of an asset to a reserved address.\n /// @param to The intended recipient (reserved address) of the ERC1155 tokens.\n /// @param assetIds The array of IDs of the asset tokens.\n /// @param assetValues The amounts of each token ID to transfer.\n /// @param proof The proof submitted for verification.\n /// @param salt The salt submitted for verification.\n function claimAssets(\n address to,\n uint256[] calldata assetIds,\n uint256[] calldata assetValues,\n bytes32[] calldata proof,\n bytes32 salt\n ) external {\n require(block.timestamp < _expiryTime, \"CLAIM_PERIOD_IS_OVER\");\n require(to != address(0), \"INVALID_TO_ZERO_ADDRESS\");\n require(claimed[to] == false, \"DESTINATION_ALREADY_CLAIMED\");\n claimed[to] = true;\n _claimERC1155(to, assetIds, assetValues, proof, salt);\n }\n\n function onERC1155Received(\n address, /*operator*/\n address, /*from*/\n uint256, /*id*/\n uint256, /*value*/\n bytes calldata /*data*/\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address, /*operator*/\n address, /*from*/\n uint256[] calldata, /*ids*/\n uint256[] calldata, /*values*/\n bytes calldata /*data*/\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n}\n" + }, + "src/solc_0.8/claims/AssetGiveaway/ClaimERC1155.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/token/ERC1155/IERC1155.sol\";\n\ncontract ClaimERC1155 {\n bytes32 internal _merkleRoot;\n IERC1155 internal immutable _asset;\n address internal immutable _assetsHolder;\n event ClaimedAssets(address to, uint256[] assetIds, uint256[] assetValues);\n\n constructor(IERC1155 asset, address assetsHolder) {\n _asset = asset;\n if (assetsHolder == address(0)) {\n assetsHolder = address(this);\n }\n _assetsHolder = assetsHolder;\n }\n\n /// @dev See for example AssetGiveaway.sol claimAssets.\n function _claimERC1155(\n address to,\n uint256[] calldata assetIds,\n uint256[] calldata assetValues,\n bytes32[] calldata proof,\n bytes32 salt\n ) internal {\n _checkValidity(to, assetIds, assetValues, proof, salt);\n _sendAssets(to, assetIds, assetValues);\n emit ClaimedAssets(to, assetIds, assetValues);\n }\n\n function _checkValidity(\n address to,\n uint256[] memory assetIds,\n uint256[] memory assetValues,\n bytes32[] memory proof,\n bytes32 salt\n ) internal view {\n require(assetIds.length == assetValues.length, \"INVALID_INPUT\");\n bytes32 leaf = _generateClaimHash(to, assetIds, assetValues, salt);\n require(_verify(proof, leaf), \"INVALID_CLAIM\");\n }\n\n function _generateClaimHash(\n address to,\n uint256[] memory assetIds,\n uint256[] memory assetValues,\n bytes32 salt\n ) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(to, assetIds, assetValues, salt));\n }\n\n function _verify(bytes32[] memory proof, bytes32 computedHash) internal view returns (bool) {\n for (uint256 i = 0; i < proof.length; i++) {\n bytes32 proofElement = proof[i];\n\n if (computedHash < proofElement) {\n computedHash = keccak256(abi.encodePacked(computedHash, proofElement));\n } else {\n computedHash = keccak256(abi.encodePacked(proofElement, computedHash));\n }\n }\n\n return computedHash == _merkleRoot;\n }\n\n function _sendAssets(\n address to,\n uint256[] memory assetIds,\n uint256[] memory assetValues\n ) internal {\n _asset.safeBatchTransferFrom(_assetsHolder, to, assetIds, assetValues, \"\");\n }\n}\n" + }, + "src/solc_0.8/claims/MultiGiveaway/ClaimERC1155ERC721ERC20.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {IERC1155} from \"@openzeppelin/contracts-0.8/token/ERC1155/IERC1155.sol\";\nimport {IERC20} from \"@openzeppelin/contracts-0.8/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts-0.8/token/ERC20/utils/SafeERC20.sol\";\nimport {MerkleProof} from \"@openzeppelin/contracts-0.8/utils/cryptography/MerkleProof.sol\";\nimport {IERC721Extended} from \"../../common/interfaces/IERC721Extended.sol\";\n\ncontract ClaimERC1155ERC721ERC20 {\n using SafeERC20 for IERC20;\n\n struct Claim {\n address to;\n ERC1155Claim[] erc1155;\n ERC721Claim[] erc721;\n ERC20Claim erc20;\n bytes32 salt;\n }\n\n struct ERC1155Claim {\n uint256[] ids;\n uint256[] values;\n address contractAddress;\n }\n\n struct ERC721Claim {\n uint256[] ids;\n address contractAddress;\n }\n\n struct ERC20Claim {\n uint256[] amounts;\n address[] contractAddresses;\n }\n\n /// @dev Emits when a successful claim occurs.\n /// @param to The destination address for the claimed ERC1155, ERC721 and ERC20 tokens.\n /// @param erc1155 The array of ERC1155Claim structs containing the ids, values and ERC1155 contract address.\n /// @param erc721 The array of ERC721Claim structs containing the ids and ERC721 contract address.\n /// @param erc20 The ERC20Claim struct containing the amounts and ERC20 contract addresses.\n /// @param merkleRoot The merkle root hash for the specific set of items being claimed.\n event ClaimedMultipleTokens(\n address to,\n ERC1155Claim[] erc1155,\n ERC721Claim[] erc721,\n ERC20Claim erc20,\n bytes32 merkleRoot\n );\n\n /// @dev Internal function used to claim multiple token types in one claim.\n /// @param merkleRoot The merkle root hash for the specific set of items being claimed.\n /// @param claim The claim struct containing the destination address, all items to be claimed and optional salt param.\n /// @param proof The proof provided by the user performing the claim function.\n function _claimERC1155ERC721ERC20(\n bytes32 merkleRoot,\n Claim memory claim,\n bytes32[] calldata proof\n ) internal {\n _checkValidity(merkleRoot, claim, proof);\n for (uint256 i = 0; i < claim.erc1155.length; i++) {\n require(claim.erc1155[i].ids.length == claim.erc1155[i].values.length, \"CLAIM_INVALID_INPUT\");\n _transferERC1155(claim.to, claim.erc1155[i].ids, claim.erc1155[i].values, claim.erc1155[i].contractAddress);\n }\n for (uint256 i = 0; i < claim.erc721.length; i++) {\n _transferERC721(claim.to, claim.erc721[i].ids, claim.erc721[i].contractAddress);\n }\n if (claim.erc20.amounts.length != 0) {\n require(claim.erc20.amounts.length == claim.erc20.contractAddresses.length, \"CLAIM_INVALID_INPUT\");\n _transferERC20(claim.to, claim.erc20.amounts, claim.erc20.contractAddresses);\n }\n emit ClaimedMultipleTokens(claim.to, claim.erc1155, claim.erc721, claim.erc20, merkleRoot);\n }\n\n /// @dev Private function used to check the validity of a specific claim.\n /// @param merkleRoot The merkle root hash for the specific set of items being claimed.\n /// @param claim The claim struct containing the destination address, all items to be claimed and optional salt param.\n /// @param proof The proof provided by the user performing the claim function.\n function _checkValidity(\n bytes32 merkleRoot,\n Claim memory claim,\n bytes32[] memory proof\n ) private pure {\n bytes32 leaf = _generateClaimHash(claim);\n require(MerkleProof.verify(proof, merkleRoot, leaf), \"CLAIM_INVALID\");\n }\n\n /// @dev Internal function used to generate a hash from an encoded claim.\n /// @param claim The claim struct.\n function _generateClaimHash(Claim memory claim) internal pure returns (bytes32) {\n return keccak256(abi.encode(claim));\n }\n\n /// @dev Private function used to transfer the ERC1155 tokens specified in a specific claim.\n /// @param to The destination address for the claimed tokens.\n /// @param ids The array of ERC1155 ids.\n /// @param values The amount of ERC1155 tokens of each id to be transferred.\n /// @param contractAddress The ERC1155 token contract address.\n function _transferERC1155(\n address to,\n uint256[] memory ids,\n uint256[] memory values,\n address contractAddress\n ) private {\n require(contractAddress != address(0), \"CLAIM_INVALID_CONTRACT_ZERO_ADDRESS\");\n IERC1155(contractAddress).safeBatchTransferFrom(address(this), to, ids, values, \"\");\n }\n\n /// @dev Private function used to transfer the ERC721tokens specified in a specific claim.\n /// @param to The destination address for the claimed tokens.\n /// @param ids The array of ERC721 ids.\n /// @param contractAddress The ERC721 token contract address.\n function _transferERC721(\n address to,\n uint256[] memory ids,\n address contractAddress\n ) private {\n require(contractAddress != address(0), \"CLAIM_INVALID_CONTRACT_ZERO_ADDRESS\");\n IERC721Extended(contractAddress).safeBatchTransferFrom(address(this), to, ids, \"\");\n }\n\n /// @dev Private function used to transfer the ERC20 tokens specified in a specific claim.\n /// @param to The destination address for the claimed tokens.\n /// @param amounts The array of amounts of ERC20 tokens to be transferred.\n /// @param contractAddresses The array of ERC20 token contract addresses.\n function _transferERC20(\n address to,\n uint256[] memory amounts,\n address[] memory contractAddresses\n ) private {\n for (uint256 i = 0; i < amounts.length; i++) {\n address erc20ContractAddress = contractAddresses[i];\n uint256 erc20Amount = amounts[i];\n require(erc20ContractAddress != address(0), \"CLAIM_INVALID_CONTRACT_ZERO_ADDRESS\");\n IERC20(erc20ContractAddress).safeTransferFrom(address(this), to, erc20Amount);\n }\n }\n}\n" + }, + "src/solc_0.8/claims/MultiGiveaway/MultiGiveaway.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {Context} from \"@openzeppelin/contracts-0.8/utils/Context.sol\";\nimport {ClaimERC1155ERC721ERC20} from \"./ClaimERC1155ERC721ERC20.sol\";\nimport {AccessControl} from \"@openzeppelin/contracts-0.8/access/AccessControl.sol\";\nimport {Pausable} from \"@openzeppelin/contracts-0.8/security/Pausable.sol\";\nimport {ERC2771Handler} from \"../../common/BaseWithStorage/ERC2771Handler.sol\";\n\n/// @title A Multi Claim contract that enables claims of user rewards in the form of ERC1155, ERC721 and / or ERC20 tokens\n/// @notice This contract manages claims for multiple token types\n/// @dev The contract implements ERC2771 to ensure that users do not pay gas\ncontract MultiGiveaway is AccessControl, ClaimERC1155ERC721ERC20, ERC2771Handler, Pausable {\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n bytes4 internal constant ERC721_RECEIVED = 0x150b7a02;\n bytes4 internal constant ERC721_BATCH_RECEIVED = 0x4b808c46;\n\n mapping(address => mapping(bytes32 => bool)) public claimed;\n mapping(bytes32 => uint256) internal _expiryTime;\n\n event NewGiveaway(bytes32 merkleRoot, uint256 expiryTime);\n event NewTrustedForwarder(address trustedForwarder);\n\n constructor(address admin, address trustedForwarder) {\n _setupRole(DEFAULT_ADMIN_ROLE, admin);\n __ERC2771Handler_initialize(trustedForwarder);\n }\n\n /// @notice Function to add a new giveaway.\n /// @param merkleRoot The merkle root hash of the claim data.\n /// @param expiryTime The expiry time for the giveaway.\n function addNewGiveaway(bytes32 merkleRoot, uint256 expiryTime)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n whenNotPaused()\n {\n _expiryTime[merkleRoot] = expiryTime;\n emit NewGiveaway(merkleRoot, expiryTime);\n }\n\n /// @notice set the trusted forwarder\n /// @param trustedForwarder address of the contract that is enabled to send meta-tx on behalf of the user\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n _trustedForwarder = trustedForwarder;\n\n emit NewTrustedForwarder(trustedForwarder);\n }\n\n /// @notice Function to permit the claiming of multiple tokens from multiple giveaways to a reserved address.\n /// @param claims The array of claim structs, each containing a destination address, the giveaway items to be claimed and an optional salt param.\n /// @param proofs The proofs submitted for verification.\n function claimMultipleTokensFromMultipleMerkleTree(\n bytes32[] calldata rootHashes,\n Claim[] memory claims,\n bytes32[][] calldata proofs\n ) external {\n require(claims.length == rootHashes.length, \"MULTIGIVEAWAY_INVALID_INPUT\");\n require(claims.length == proofs.length, \"MULTIGIVEAWAY_INVALID_INPUT\");\n for (uint256 i = 0; i < rootHashes.length; i++) {\n claimMultipleTokens(rootHashes[i], claims[i], proofs[i]);\n }\n }\n\n /// @notice Function to check which giveaways have been claimed by a particular user.\n /// @param user The user (intended token destination) address.\n /// @param claims The claim struct containing the destination address, all items to be claimed and optional salt param.\n /// @return claimedGiveaways The array of bools confirming whether or not the giveaways relating to the root hashes provided have been claimed.\n function getClaimedStatus(address user, Claim[] memory claims) external view returns (bool[] memory) {\n bool[] memory claimedGiveaways = new bool[](claims.length);\n for (uint256 i = 0; i < claims.length; i++) {\n bytes32 merkleLeaf = _generateClaimHash(claims[i]);\n claimedGiveaways[i] = claimed[user][merkleLeaf];\n }\n return claimedGiveaways;\n }\n\n /// @dev Public function used to perform validity checks and progress to claim multiple token types in one claim.\n /// @param merkleRoot The merkle root hash for the specific set of items being claimed.\n /// @param claim The claim struct containing the destination address, all items to be claimed and optional salt param.\n /// @param proof The proof provided by the user performing the claim function.\n function claimMultipleTokens(\n bytes32 merkleRoot,\n Claim memory claim,\n bytes32[] calldata proof\n ) public whenNotPaused() {\n uint256 giveawayExpiryTime = _expiryTime[merkleRoot];\n require(claim.to != address(0), \"MULTIGIVEAWAY_INVALID_TO_ZERO_ADDRESS\");\n require(claim.to != address(this), \"MULTIGIVEAWAY_DESTINATION_MULTIGIVEAWAY_CONTRACT\");\n require(giveawayExpiryTime != 0, \"MULTIGIVEAWAY_DOES_NOT_EXIST\");\n require(block.timestamp < giveawayExpiryTime, \"MULTIGIVEAWAY_CLAIM_PERIOD_IS_OVER\");\n bytes32 merkleLeaf = _generateClaimHash(claim);\n require(claimed[claim.to][merkleLeaf] == false, \"MULTIGIVEAWAY_DESTINATION_ALREADY_CLAIMED\");\n claimed[claim.to][merkleLeaf] = true;\n\n _claimERC1155ERC721ERC20(merkleRoot, claim, proof);\n }\n\n function onERC721Received(\n address, /*operator*/\n address, /*from*/\n uint256, /*id*/\n bytes calldata /*data*/\n ) external pure returns (bytes4) {\n return ERC721_RECEIVED;\n }\n\n function onERC721BatchReceived(\n address, /*operator*/\n address, /*from*/\n uint256[] calldata, /*ids*/\n bytes calldata /*data*/\n ) external pure returns (bytes4) {\n return ERC721_BATCH_RECEIVED;\n }\n\n function onERC1155Received(\n address, /*operator*/\n address, /*from*/\n uint256, /*id*/\n uint256, /*value*/\n bytes calldata /*data*/\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address, /*operator*/\n address, /*from*/\n uint256[] calldata, /*ids*/\n uint256[] calldata, /*values*/\n bytes calldata /*data*/\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n\n function _msgSender() internal view override(Context, ERC2771Handler) returns (address sender) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view override(Context, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n}\n" + }, + "src/solc_0.8/claims/MultiGiveawayV0/MultiGiveawayV0.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts-0.8/token/ERC1155/IERC1155Receiver.sol\";\nimport \"../MultiGiveaway/ClaimERC1155ERC721ERC20.sol\";\nimport \"../../common/BaseWithStorage/WithAdmin.sol\";\n\n/// @title MultiGiveaway contract.\n/// @notice This contract manages claims for multiple token types.\ncontract MultiGiveawayV0 is WithAdmin, ClaimERC1155ERC721ERC20 {\n /////////////////////////////// Data //////////////////////////////\n\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n bytes4 internal constant ERC721_RECEIVED = 0x150b7a02;\n bytes4 internal constant ERC721_BATCH_RECEIVED = 0x4b808c46;\n\n mapping(address => mapping(bytes32 => bool)) public claimed;\n mapping(bytes32 => uint256) internal _expiryTime;\n\n /////////////////////////////// Events //////////////////////////////\n\n event NewGiveaway(bytes32 merkleRoot, uint256 expiryTime);\n\n /////////////////////////////// Constructor /////////////////////////\n\n constructor(address admin) {\n _admin = admin;\n }\n\n /////////////////////////////// Functions ///////////////////////////\n\n /// @notice Function to add a new giveaway.\n /// @param merkleRoot The merkle root hash of the claim data.\n /// @param expiryTime The expiry time for the giveaway.\n function addNewGiveaway(bytes32 merkleRoot, uint256 expiryTime) external onlyAdmin {\n _expiryTime[merkleRoot] = expiryTime;\n emit NewGiveaway(merkleRoot, expiryTime);\n }\n\n /// @notice Function to check which giveaways have been claimed by a particular user.\n /// @param user The user (intended token destination) address.\n /// @param rootHashes The array of giveaway root hashes to check.\n /// @return claimedGiveaways The array of bools confirming whether or not the giveaways relating to the root hashes provided have been claimed.\n function getClaimedStatus(address user, bytes32[] calldata rootHashes) external view returns (bool[] memory) {\n bool[] memory claimedGiveaways = new bool[](rootHashes.length);\n for (uint256 i = 0; i < rootHashes.length; i++) {\n claimedGiveaways[i] = claimed[user][rootHashes[i]];\n }\n return claimedGiveaways;\n }\n\n /// @notice Function to permit the claiming of multiple tokens from multiple giveaways to a reserved address.\n /// @param claims The array of claim structs, each containing a destination address, the giveaway items to be claimed and an optional salt param.\n /// @param proofs The proofs submitted for verification.\n function claimMultipleTokensFromMultipleMerkleTree(\n bytes32[] calldata rootHashes,\n Claim[] memory claims,\n bytes32[][] calldata proofs\n ) external {\n require(claims.length == rootHashes.length, \"INVALID_INPUT\");\n require(claims.length == proofs.length, \"INVALID_INPUT\");\n for (uint256 i = 0; i < rootHashes.length; i++) {\n claimMultipleTokens(rootHashes[i], claims[i], proofs[i]);\n }\n }\n\n /// @dev Public function used to perform validity checks and progress to claim multiple token types in one claim.\n /// @param merkleRoot The merkle root hash for the specific set of items being claimed.\n /// @param claim The claim struct containing the destination address, all items to be claimed and optional salt param.\n /// @param proof The proof provided by the user performing the claim function.\n function claimMultipleTokens(\n bytes32 merkleRoot,\n Claim memory claim,\n bytes32[] calldata proof\n ) public {\n uint256 giveawayExpiryTime = _expiryTime[merkleRoot];\n require(claim.to != address(0), \"INVALID_TO_ZERO_ADDRESS\");\n require(claim.to != address(this), \"DESTINATION_MULTIGIVEAWAY_CONTRACT\");\n require(giveawayExpiryTime != 0, \"GIVEAWAY_DOES_NOT_EXIST\");\n require(block.timestamp < giveawayExpiryTime, \"CLAIM_PERIOD_IS_OVER\");\n require(claimed[claim.to][merkleRoot] == false, \"DESTINATION_ALREADY_CLAIMED\");\n claimed[claim.to][merkleRoot] = true;\n _claimERC1155ERC721ERC20(merkleRoot, claim, proof);\n }\n\n function onERC721Received(\n address, /*operator*/\n address, /*from*/\n uint256, /*id*/\n bytes calldata /*data*/\n ) external pure returns (bytes4) {\n return ERC721_RECEIVED;\n }\n\n function onERC721BatchReceived(\n address, /*operator*/\n address, /*from*/\n uint256[] calldata, /*ids*/\n bytes calldata /*data*/\n ) external pure returns (bytes4) {\n return ERC721_BATCH_RECEIVED;\n }\n\n function onERC1155Received(\n address, /*operator*/\n address, /*from*/\n uint256, /*id*/\n uint256, /*value*/\n bytes calldata /*data*/\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address, /*operator*/\n address, /*from*/\n uint256[] calldata, /*ids*/\n uint256[] calldata, /*values*/\n bytes calldata /*data*/\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n}\n" + }, + "src/solc_0.8/claims/signedGiveaway/SignedERC20Giveaway.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {EIP712Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport {IERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport {ERC2771Handler} from \"../../common/BaseWithStorage/ERC2771Handler.sol\";\nimport {ContextUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport {ECDSAUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\";\nimport {AccessControlUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\n\n/// @title This contract pays Sand claims when the backend authorize it via message signing.\n/// @dev can be extended to support NFTs, etc.\n/// @dev This contract support meta transactions.\n/// @dev This contract is final, don't inherit form it.\ncontract SignedERC20Giveaway is\n Initializable,\n ContextUpgradeable,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n ERC2771Handler,\n PausableUpgradeable\n{\n event Claimed(address indexed signer, uint256 claimId, address indexed token, address indexed to, uint256 amount);\n event RevokedClaims(uint256[] claimIds);\n\n bytes32 public constant SIGNER_ROLE = keccak256(\"SIGNER_ROLE\");\n bytes32 public constant CLAIM_TYPEHASH =\n keccak256(\"Claim(address signer,uint256 claimId,address token,address to,uint256 amount)\");\n string public constant name = \"Sandbox SignedERC20Giveaway\";\n string public constant version = \"1.0\";\n mapping(uint256 => bool) public claimed;\n\n function initialize(address trustedForwarder_, address defaultAdmin_) external initializer {\n __Context_init_unchained();\n __ERC165_init_unchained();\n __AccessControl_init_unchained();\n __EIP712_init_unchained(name, version);\n __ERC2771Handler_initialize(trustedForwarder_);\n __Pausable_init_unchained();\n _setupRole(DEFAULT_ADMIN_ROLE, defaultAdmin_);\n }\n\n /// @notice verifies a ERC712 signature for the Mint data type.\n /// @param v signature part\n /// @param r signature part\n /// @param s signature part\n /// @param signer the address of the signer, must be part of the signer role\n /// @param claimId unique claim id\n /// @param token token contract address\n /// @param to destination user\n /// @param amount of ERC20 to transfer\n /// @return true if the signature is valid\n function verify(\n uint8 v,\n bytes32 r,\n bytes32 s,\n address signer,\n uint256 claimId,\n address token,\n address to,\n uint256 amount\n ) external view returns (bool) {\n return _verify(v, r, s, signer, claimId, token, to, amount);\n }\n\n /// @notice verifies a ERC712 signature and mint a new NFT for the buyer.\n /// @param v signature part\n /// @param r signature part\n /// @param s signature part\n /// @param signer the address of the signer, must be part of the signer role\n /// @param claimId unique claim id\n /// @param token token contract address\n /// @param to destination user\n /// @param amount of ERC20 to transfer\n function claim(\n uint8 v,\n bytes32 r,\n bytes32 s,\n address signer,\n uint256 claimId,\n address token,\n address to,\n uint256 amount\n ) external whenNotPaused {\n require(_verify(v, r, s, signer, claimId, token, to, amount), \"Invalid signature\");\n require(hasRole(SIGNER_ROLE, signer), \"Invalid signer\");\n require(!claimed[claimId], \"Already claimed\");\n claimed[claimId] = true;\n require(IERC20Upgradeable(token).transfer(to, amount), \"Transfer failed\");\n emit Claimed(signer, claimId, token, to, amount);\n }\n\n /// @notice let the admin revoke some claims so they cannot be used\n /// @param claimIds and array of claim Ids to revoke\n function revokeClaims(uint256[] calldata claimIds) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), \"Only admin\");\n for (uint256 i = 0; i < claimIds.length; i++) {\n claimed[claimIds[i]] = true;\n }\n emit RevokedClaims(claimIds);\n }\n\n // @dev Triggers stopped state.\n // The contract must not be paused.\n function pause() external {\n require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), \"Only admin\");\n _pause();\n }\n\n // @dev Returns to normal state.\n // The contract must be paused.\n function unpause() external {\n require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), \"Only admin\");\n _unpause();\n }\n\n function domainSeparator() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n function getChainId() external view returns (uint256) {\n return block.chainid;\n }\n\n function _msgSender() internal view override(ContextUpgradeable, ERC2771Handler) returns (address sender) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n\n function _verify(\n uint8 v,\n bytes32 r,\n bytes32 s,\n address signer,\n uint256 claimId,\n address token,\n address to,\n uint256 amount\n ) internal view returns (bool) {\n bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(CLAIM_TYPEHASH, signer, claimId, token, to, amount)));\n address recoveredSigner = ECDSAUpgradeable.recover(digest, v, r, s);\n return recoveredSigner == signer;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view override(AccessControlUpgradeable) returns (bool) {\n return super.supportsInterface(interfaceId);\n }\n}\n" + }, + "src/solc_0.8/common/Base/TheSandbox712.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\ncontract TheSandbox712 {\n bytes32 internal constant EIP712DOMAIN_TYPEHASH =\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n // solhint-disable-next-line var-name-mixedcase\n bytes32 public immutable _DOMAIN_SEPARATOR;\n\n constructor() {\n _DOMAIN_SEPARATOR = keccak256(\n // chainId 137 = Polygon\n abi.encode(EIP712DOMAIN_TYPEHASH, keccak256(\"The Sandbox\"), keccak256(\"1\"), block.chainid, address(this))\n );\n }\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/ERC20/ERC20BaseToken.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/utils/Context.sol\";\nimport \"./extensions/ERC20Internal.sol\";\nimport \"../../interfaces/IERC20Extended.sol\";\nimport \"../WithSuperOperators.sol\";\n\nabstract contract ERC20BaseToken is WithSuperOperators, IERC20, IERC20Extended, ERC20Internal, Context {\n string internal _name;\n string internal _symbol;\n address internal immutable _operator;\n uint256 internal _totalSupply;\n mapping(address => uint256) internal _balances;\n mapping(address => mapping(address => uint256)) internal _allowances;\n\n constructor(\n string memory tokenName,\n string memory tokenSymbol,\n address admin,\n address operator\n ) {\n _name = tokenName;\n _symbol = tokenSymbol;\n _admin = admin;\n _operator = operator;\n }\n\n /// @notice Transfer `amount` tokens to `to`.\n /// @param to The recipient address of the tokens being transfered.\n /// @param amount The number of tokens being transfered.\n /// @return success Whether or not the transfer succeeded.\n function transfer(address to, uint256 amount) external override returns (bool success) {\n _transfer(_msgSender(), to, amount);\n return true;\n }\n\n /// @notice Transfer `amount` tokens from `from` to `to`.\n /// @param from The origin address of the tokens being transferred.\n /// @param to The recipient address of the tokensbeing transfered.\n /// @param amount The number of tokens transfered.\n /// @return success Whether or not the transfer succeeded.\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external override returns (bool success) {\n if (_msgSender() != from && !_superOperators[_msgSender()] && _msgSender() != _operator) {\n uint256 currentAllowance = _allowances[from][_msgSender()];\n if (currentAllowance != ~uint256(0)) {\n // save gas when allowance is maximal by not reducing it (see https://github.com/ethereum/EIPs/issues/717)\n require(currentAllowance >= amount, \"NOT_AUTHORIZED_ALLOWANCE\");\n _allowances[from][_msgSender()] = currentAllowance - amount;\n }\n }\n _transfer(from, to, amount);\n return true;\n }\n\n /// @notice Burn `amount` tokens.\n /// @param amount The number of tokens to burn.\n function burn(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n /// @notice Burn `amount` tokens from `owner`.\n /// @param from The address whose token to burn.\n /// @param amount The number of tokens to burn.\n function burnFor(address from, uint256 amount) external override {\n _burn(from, amount);\n }\n\n /// @notice Approve `spender` to transfer `amount` tokens.\n /// @param spender The address to be given rights to transfer.\n /// @param amount The number of tokens allowed.\n /// @return success Whether or not the call succeeded.\n function approve(address spender, uint256 amount) external override returns (bool success) {\n _approveFor(_msgSender(), spender, amount);\n return true;\n }\n\n /// @notice Get the name of the token collection.\n /// @return The name of the token collection.\n function name() external view virtual returns (string memory) {\n //added virtual\n return _name;\n }\n\n /// @notice Get the symbol for the token collection.\n /// @return The symbol of the token collection.\n function symbol() external view virtual returns (string memory) {\n //added virtual\n return _symbol;\n }\n\n /// @notice Get the total number of tokens in existence.\n /// @return The total number of tokens in existence.\n function totalSupply() external view override returns (uint256) {\n return _totalSupply;\n }\n\n /// @notice Get the balance of `owner`.\n /// @param owner The address to query the balance of.\n /// @return The amount owned by `owner`.\n function balanceOf(address owner) external view override returns (uint256) {\n return _balances[owner];\n }\n\n /// @notice Get the allowance of `spender` for `owner`'s tokens.\n /// @param owner The address whose token is allowed.\n /// @param spender The address allowed to transfer.\n /// @return remaining The amount of token `spender` is allowed to transfer on behalf of `owner`.\n function allowance(address owner, address spender) external view override returns (uint256 remaining) {\n return _allowances[owner][spender];\n }\n\n /// @notice Get the number of decimals for the token collection.\n /// @return The number of decimals.\n function decimals() external pure virtual returns (uint8) {\n return uint8(18);\n }\n\n /// @notice Approve `spender` to transfer `amount` tokens from `owner`.\n /// @param owner The address whose token is allowed.\n /// @param spender The address to be given rights to transfer.\n /// @param amount The number of tokens allowed.\n /// @return success Whether or not the call succeeded.\n function approveFor(\n address owner,\n address spender,\n uint256 amount\n ) public override returns (bool success) {\n require(_msgSender() == owner || _superOperators[_msgSender()] || _msgSender() == _operator, \"NOT_AUTHORIZED\");\n _approveFor(owner, spender, amount);\n return true;\n }\n\n /// @notice Increase the allowance for the spender if needed\n /// @param owner The address of the owner of the tokens\n /// @param spender The address wanting to spend tokens\n /// @param amountNeeded The amount requested to spend\n /// @return success Whether or not the call succeeded.\n function addAllowanceIfNeeded(\n address owner,\n address spender,\n uint256 amountNeeded\n ) public returns (bool success) {\n require(_msgSender() == owner || _superOperators[_msgSender()] || _msgSender() == _operator, \"INVALID_SENDER\");\n _addAllowanceIfNeeded(owner, spender, amountNeeded);\n return true;\n }\n\n /// @dev See addAllowanceIfNeeded.\n function _addAllowanceIfNeeded(\n address owner,\n address spender,\n uint256 amountNeeded /*(ERC20Internal, ERC20ExecuteExtension, ERC20BasicApproveExtension)*/\n ) internal virtual override {\n if (amountNeeded > 0 && !isSuperOperator(spender) && spender != _operator) {\n uint256 currentAllowance = _allowances[owner][spender];\n if (currentAllowance < amountNeeded) {\n _approveFor(owner, spender, amountNeeded);\n }\n }\n }\n\n /// @dev See approveFor.\n function _approveFor(\n address owner,\n address spender,\n uint256 amount /*(ERC20BasicApproveExtension, ERC20Internal)*/\n ) internal virtual override {\n require(owner != address(0) && spender != address(0), \"INVALID_OWNER_||_SPENDER\");\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /// @dev See transfer.\n function _transfer(\n address from,\n address to,\n uint256 amount /*(ERC20Internal, ERC20ExecuteExtension)*/\n ) internal virtual override {\n require(to != address(0), \"NOT_TO_ZEROADDRESS\");\n require(to != address(this), \"NOT_TO_THIS\");\n uint256 currentBalance = _balances[from];\n require(currentBalance >= amount, \"INSUFFICIENT_FUNDS\");\n _balances[from] = currentBalance - amount;\n _balances[to] += amount;\n emit Transfer(from, to, amount);\n }\n\n /// @dev Mint tokens for a recipient.\n /// @param to The recipient address.\n /// @param amount The number of token to mint.\n function _mint(address to, uint256 amount) internal {\n require(to != address(0), \"NOT_TO_ZEROADDRESS\");\n require(amount > 0, \"MINT_O_TOKENS\");\n uint256 currentTotalSupply = _totalSupply;\n uint256 newTotalSupply = currentTotalSupply + amount;\n require(newTotalSupply > currentTotalSupply, \"OVERFLOW\");\n _totalSupply = newTotalSupply;\n _balances[to] += amount;\n emit Transfer(address(0), to, amount);\n }\n\n /// @dev Burn tokens from an address.\n /// @param from The address whose tokens to burn.\n /// @param amount The number of token to burn.\n function _burn(address from, uint256 amount) internal {\n require(amount > 0, \"BURN_O_TOKENS\");\n if (_msgSender() != from && !_superOperators[_msgSender()] && _msgSender() != _operator) {\n uint256 currentAllowance = _allowances[from][_msgSender()];\n if (currentAllowance != ~uint256(0)) {\n // save gas when allowance is maximal by not reducing it (see https://github.com/ethereum/EIPs/issues/717)\n require(currentAllowance >= amount, \"INSUFFICIENT_ALLOWANCE\");\n _allowances[from][_msgSender()] = currentAllowance - amount;\n }\n }\n\n uint256 currentBalance = _balances[from];\n require(currentBalance >= amount, \"INSUFFICIENT_FUNDS\");\n _balances[from] = currentBalance - amount;\n _totalSupply -= amount;\n emit Transfer(from, address(0), amount);\n }\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/ERC20/ERC20BaseTokenUpgradeable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-upgradeable/metatx/ERC2771ContextUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"./extensions/ERC20Internal.sol\";\nimport \"../../interfaces/IERC20Extended.sol\";\n\nabstract contract ERC20BaseTokenUpgradeable is\n IERC20,\n IERC20Extended,\n ERC20Internal,\n ERC2771ContextUpgradeable,\n AccessControlUpgradeable\n{\n bytes32 public constant SUPER_OPERATOR_ROLE = keccak256(\"SUPER_OPERATOR_ROLE\");\n\n string internal _name;\n string internal _symbol;\n uint256 internal _totalSupply;\n mapping(address => uint256) internal _balances;\n mapping(address => mapping(address => uint256)) internal _allowances;\n\n uint256[50] private __gap;\n\n function __ERC20BaseTokenUpgradeable_init(\n string memory tokenName,\n string memory tokenSymbol,\n address trustedForwarder,\n address admin\n ) internal initializer {\n _name = tokenName;\n _symbol = tokenSymbol;\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, admin);\n __ERC2771Context_init(trustedForwarder);\n }\n\n /// @notice Transfer `amount` tokens to `to`.\n /// @param to The recipient address of the tokens being transfered.\n /// @param amount The number of tokens being transfered.\n /// @return success Whether or not the transfer succeeded.\n function transfer(address to, uint256 amount) external override returns (bool success) {\n _transfer(_msgSender(), to, amount);\n return true;\n }\n\n /// @notice Transfer `amount` tokens from `from` to `to`.\n /// @param from The origin address of the tokens being transferred.\n /// @param to The recipient address of the tokensbeing transfered.\n /// @param amount The number of tokens transfered.\n /// @return success Whether or not the transfer succeeded.\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external override returns (bool success) {\n if (_msgSender() != from && !hasRole(SUPER_OPERATOR_ROLE, _msgSender())) {\n uint256 currentAllowance = _allowances[from][_msgSender()];\n if (currentAllowance != ~uint256(0)) {\n // save gas when allowance is maximal by not reducing it (see https://github.com/ethereum/EIPs/issues/717)\n require(currentAllowance >= amount, \"NOT_AUTHORIZED_ALLOWANCE\");\n _allowances[from][_msgSender()] = currentAllowance - amount;\n }\n }\n _transfer(from, to, amount);\n return true;\n }\n\n /// @notice Burn `amount` tokens.\n /// @param amount The number of tokens to burn.\n function burn(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n /// @notice Burn `amount` tokens from `owner`.\n /// @param from The address whose token to burn.\n /// @param amount The number of tokens to burn.\n function burnFor(address from, uint256 amount) external override {\n _burn(from, amount);\n }\n\n /// @notice Approve `spender` to transfer `amount` tokens.\n /// @param spender The address to be given rights to transfer.\n /// @param amount The number of tokens allowed.\n /// @return success Whether or not the call succeeded.\n function approve(address spender, uint256 amount) external override returns (bool success) {\n _approveFor(_msgSender(), spender, amount);\n return true;\n }\n\n /// @notice Get the name of the token collection.\n /// @return The name of the token collection.\n function name() external view virtual returns (string memory) {\n //added virtual\n return _name;\n }\n\n /// @notice Get the symbol for the token collection.\n /// @return The symbol of the token collection.\n function symbol() external view virtual returns (string memory) {\n //added virtual\n return _symbol;\n }\n\n /// @notice Get the total number of tokens in existence.\n /// @return The total number of tokens in existence.\n function totalSupply() external view override returns (uint256) {\n return _totalSupply;\n }\n\n /// @notice Get the balance of `owner`.\n /// @param owner The address to query the balance of.\n /// @return The amount owned by `owner`.\n function balanceOf(address owner) external view override returns (uint256) {\n return _balances[owner];\n }\n\n /// @notice Get the allowance of `spender` for `owner`'s tokens.\n /// @param owner The address whose token is allowed.\n /// @param spender The address allowed to transfer.\n /// @return remaining The amount of token `spender` is allowed to transfer on behalf of `owner`.\n function allowance(address owner, address spender) external view override returns (uint256 remaining) {\n return _allowances[owner][spender];\n }\n\n /// @notice Get the number of decimals for the token collection.\n /// @return The number of decimals.\n function decimals() public pure virtual returns (uint8) {\n return uint8(18);\n }\n\n /// @notice Approve `spender` to transfer `amount` tokens from `owner`.\n /// @param owner The address whose token is allowed.\n /// @param spender The address to be given rights to transfer.\n /// @param amount The number of tokens allowed.\n /// @return success Whether or not the call succeeded.\n function approveFor(\n address owner,\n address spender,\n uint256 amount\n ) external virtual override returns (bool success) {\n require(_msgSender() == owner || hasRole(SUPER_OPERATOR_ROLE, _msgSender()), \"NOT_AUTHORIZED\");\n _approveFor(owner, spender, amount);\n return true;\n }\n\n /// @notice Increase the allowance for the spender if needed\n /// @param owner The address of the owner of the tokens\n /// @param spender The address wanting to spend tokens\n /// @param amountNeeded The amount requested to spend\n /// @return success Whether or not the call succeeded.\n function addAllowanceIfNeeded(\n address owner,\n address spender,\n uint256 amountNeeded\n ) external returns (bool success) {\n require(_msgSender() == owner || hasRole(SUPER_OPERATOR_ROLE, _msgSender()), \"INVALID_SENDER\");\n _addAllowanceIfNeeded(owner, spender, amountNeeded);\n return true;\n }\n\n /// @dev See addAllowanceIfNeeded.\n function _addAllowanceIfNeeded(\n address owner,\n address spender,\n uint256 amountNeeded\n ) internal virtual override {\n if (amountNeeded > 0 && !hasRole(SUPER_OPERATOR_ROLE, _msgSender())) {\n uint256 currentAllowance = _allowances[owner][spender];\n if (currentAllowance < amountNeeded) {\n _approveFor(owner, spender, amountNeeded);\n }\n }\n }\n\n /// @dev See approveFor.\n function _approveFor(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual override {\n require(owner != address(0) && spender != address(0), \"INVALID_OWNER_||_SPENDER\");\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /// @dev See transfer.\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n require(to != address(0), \"NOT_TO_ZEROADDRESS\");\n require(to != address(this), \"NOT_TO_THIS\");\n uint256 currentBalance = _balances[from];\n require(currentBalance >= amount, \"INSUFFICIENT_FUNDS\");\n _balances[from] = currentBalance - amount;\n _balances[to] += amount;\n emit Transfer(from, to, amount);\n }\n\n /// @dev Mint tokens for a recipient.\n /// @param to The recipient address.\n /// @param amount The number of token to mint.\n function _mint(address to, uint256 amount) internal {\n require(to != address(0), \"NOT_TO_ZEROADDRESS\");\n require(amount > 0, \"MINT_O_TOKENS\");\n uint256 currentTotalSupply = _totalSupply;\n uint256 newTotalSupply = currentTotalSupply + amount;\n require(newTotalSupply > currentTotalSupply, \"OVERFLOW\");\n _totalSupply = newTotalSupply;\n _balances[to] += amount;\n emit Transfer(address(0), to, amount);\n }\n\n /// @dev Burn tokens from an address.\n /// @param from The address whose tokens to burn.\n /// @param amount The number of token to burn.\n function _burn(address from, uint256 amount) internal {\n require(amount > 0, \"BURN_O_TOKENS\");\n if (_msgSender() != from && !hasRole(SUPER_OPERATOR_ROLE, _msgSender())) {\n uint256 currentAllowance = _allowances[from][_msgSender()];\n if (currentAllowance != ~uint256(0)) {\n // save gas when allowance is maximal by not reducing it (see https://github.com/ethereum/EIPs/issues/717)\n require(currentAllowance >= amount, \"INSUFFICIENT_ALLOWANCE\");\n _allowances[from][_msgSender()] = currentAllowance - amount;\n }\n }\n uint256 currentBalance = _balances[from];\n require(currentBalance >= amount, \"INSUFFICIENT_FUNDS\");\n _balances[from] = currentBalance - amount;\n _totalSupply -= amount;\n emit Transfer(from, address(0), amount);\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771ContextUpgradeable)\n returns (address sender)\n {\n return ERC2771ContextUpgradeable._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771ContextUpgradeable)\n returns (bytes calldata)\n {\n return ERC2771ContextUpgradeable._msgData();\n }\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/ERC20/ERC20TokenUpgradeable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"./ERC20BaseTokenUpgradeable.sol\";\nimport \"../WithPermitUpgradeable.sol\";\nimport \"../ERC677/extensions/ERC677Extension.sol\";\nimport \"../../interfaces/IERC677Receiver.sol\";\n\ncontract ERC20TokenUpgradeable is ERC677Extension, WithPermitUpgradeable, ERC20BaseTokenUpgradeable {\n function __ERC20TokenUpgradeable_init(\n string memory name,\n string memory symbol,\n address trustedForwarder,\n address admin\n ) public initializer {\n __ERC20BaseTokenUpgradeable_init(name, symbol, trustedForwarder, admin);\n __WithPermitUpgradeable_init(\"The Sandbox\");\n }\n\n function mint(address to, uint256 amount) external onlyRole(DEFAULT_ADMIN_ROLE) {\n _mint(to, amount);\n }\n\n /// @notice Function to permit the expenditure of ERC20 token by a nominated spender\n /// @param owner The owner of the ERC20 tokens\n /// @param spender The nominated spender of the ERC20 tokens\n /// @param value The value (allowance) of the ERC20 tokens that the nominated spender will be allowed to spend\n /// @param deadline The deadline for granting permission to the spender\n /// @param v The final 1 byte of signature\n /// @param r The first 32 bytes of signature\n /// @param s The second 32 bytes of signature\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public override {\n checkApproveFor(owner, spender, value, deadline, v, r, s);\n _approveFor(owner, spender, value);\n }\n\n function _msgSender() internal view override(Context, ERC20BaseTokenUpgradeable) returns (address sender) {\n return ERC2771ContextUpgradeable._msgSender();\n }\n\n function _msgData() internal view override(Context, ERC20BaseTokenUpgradeable) returns (bytes calldata) {\n return ERC2771ContextUpgradeable._msgData();\n }\n\n uint256[50] private __gap;\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/ERC20/extensions/ERC20BasicApproveExtension.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/utils/Context.sol\";\nimport \"./ERC20Internal.sol\";\nimport \"../../../Libraries/BytesUtil.sol\";\n\nabstract contract ERC20BasicApproveExtension is ERC20Internal, Context {\n /// @notice Approve `target` to spend `amount` and call it with data.\n /// @param target The address to be given rights to transfer and destination of the call.\n /// @param amount The number of tokens allowed.\n /// @param data The bytes for the call.\n /// @return The data of the call.\n function approveAndCall(\n address target,\n uint256 amount,\n bytes calldata data\n ) external payable returns (bytes memory) {\n require(BytesUtil.doFirstParamEqualsAddress(data, _msgSender()), \"FIRST_PARAM_NOT_SENDER\");\n\n _approveFor(_msgSender(), target, amount);\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returnData) = target.call{value: msg.value}(data);\n require(success, string(returnData));\n return returnData;\n }\n\n /// @notice Temporarily approve `target` to spend `amount` and call it with data.\n /// Previous approvals remains unchanged.\n /// @param target The destination of the call, allowed to spend the amount specified\n /// @param amount The number of tokens allowed to spend.\n /// @param data The bytes for the call.\n /// @return The data of the call.\n function paidCall(\n address target,\n uint256 amount,\n bytes calldata data\n ) external payable returns (bytes memory) {\n require(BytesUtil.doFirstParamEqualsAddress(data, _msgSender()), \"FIRST_PARAM_NOT_SENDER\");\n\n if (amount > 0) {\n _addAllowanceIfNeeded(_msgSender(), target, amount);\n }\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returnData) = target.call{value: msg.value}(data);\n require(success, string(returnData));\n\n return returnData;\n }\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/ERC20/extensions/ERC20Internal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nabstract contract ERC20Internal {\n function _approveFor(\n address owner,\n address target,\n uint256 amount\n ) internal virtual;\n\n function _addAllowanceIfNeeded(\n address owner,\n address spender,\n uint256 amountNeeded\n ) internal virtual;\n\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual;\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/ERC2771/ERC2771HandlerUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/metatx/ERC2771Context.sol\n/// with an initializer for proxies and a mutable forwarder\n/// @dev same as ERC2771Handler.sol but with gap\n\ncontract ERC2771HandlerUpgradeable {\n address internal _trustedForwarder;\n uint256[49] private __gap;\n\n function __ERC2771Handler_initialize(address forwarder) internal {\n _trustedForwarder = forwarder;\n }\n\n function isTrustedForwarder(address forwarder) public view returns (bool) {\n return forwarder == _trustedForwarder;\n }\n\n function getTrustedForwarder() external view returns (address trustedForwarder) {\n return _trustedForwarder;\n }\n\n function _msgSender() internal view virtual returns (address sender) {\n if (isTrustedForwarder(msg.sender)) {\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n if (isTrustedForwarder(msg.sender)) {\n return msg.data[:msg.data.length - 20];\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/ERC2771/ERC2771HandlerV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// @dev no initializer version\n\ncontract ERC2771HandlerV2 {\n address internal _trustedForwarder;\n\n constructor(address forwarder) {\n _trustedForwarder = forwarder;\n }\n\n function isTrustedForwarder(address forwarder) public view returns (bool) {\n return forwarder == _trustedForwarder;\n }\n\n function getTrustedForwarder() external view returns (address trustedForwarder) {\n return _trustedForwarder;\n }\n\n function _msgSender() internal view virtual returns (address sender) {\n if (isTrustedForwarder(msg.sender)) {\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n if (isTrustedForwarder(msg.sender)) {\n return msg.data[:msg.data.length - 20];\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/ERC2771Handler.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\n/**\n * @title ERC2771Handler\n * @author The Sandbox\n * @notice Handle meta-transactions\n * @dev minimal ERC2771 handler to keep bytecode-size down\n * based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/metatx/ERC2771Context.sol\n * with an initializer for proxies and a mutable forwarder\n */\nabstract contract ERC2771Handler {\n address internal _trustedForwarder;\n\n event TrustedForwarderSet(address indexed newForwarder);\n\n /**\n * @dev Initializes the contract\n * @param forwarder trusted forwarder address\n */\n function __ERC2771Handler_initialize(address forwarder) internal {\n _trustedForwarder = forwarder;\n emit TrustedForwarderSet(_trustedForwarder);\n }\n\n /**\n * @notice Checks if an address is a trusted forwarder\n * @param forwarder address to check\n * @return is trusted\n */\n function isTrustedForwarder(address forwarder) public view returns (bool) {\n return forwarder == _trustedForwarder;\n }\n\n /**\n * @notice Get the current trusted forwarder\n * @return trustedForwarder address of the trusted forwarder\n */\n function getTrustedForwarder() external view returns (address) {\n return _trustedForwarder;\n }\n\n /**\n * @dev if the call comes from the trusted forwarder, it gets the real sender by checking the encoded address in the data\n * @return sender address of the real sender\n */\n function _msgSender() internal view virtual returns (address sender) {\n if (isTrustedForwarder(msg.sender)) {\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n /**\n * @dev if the call comes from the trusted forwarder, it substracts the sender address from `msg.data` to get the real `msg.data`\n * @return the real `msg.data`\n */\n function _msgData() internal view virtual returns (bytes calldata) {\n if (isTrustedForwarder(msg.sender)) {\n return msg.data[:msg.data.length - 20];\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/ERC2771HandlerV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down.\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\n\nabstract contract ERC2771HandlerV2 {\n address internal _trustedForwarder;\n\n function __ERC2771HandlerV2_initialize(address forwarder) internal {\n _trustedForwarder = forwarder;\n }\n\n function isTrustedForwarder(address forwarder) public view returns (bool) {\n return forwarder == _trustedForwarder;\n }\n\n function getTrustedForwarder() external view returns (address trustedForwarder) {\n return _trustedForwarder;\n }\n\n function _msgSender() internal view virtual returns (address sender) {\n if (isTrustedForwarder(msg.sender)) {\n require(msg.data.length >= 24, \"ERC2771HandlerV2: Invalid msg.data\");\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n if (isTrustedForwarder(msg.sender)) {\n require(msg.data.length >= 24, \"ERC2771HandlerV2: Invalid msg.data\");\n return msg.data[:msg.data.length - 20];\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/ERC2771HandlerV3.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down.\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\n\nabstract contract ERC2771HandlerV3 {\n address internal _trustedForwarder;\n\n function __ERC2771HandlerV3_initialize(address forwarder) internal {\n _trustedForwarder = forwarder;\n }\n\n /// @notice check if an given address is a trusted forwarder\n /// @param forwarder address to check\n function isTrustedForwarder(address forwarder) public view returns (bool) {\n return forwarder == _trustedForwarder;\n }\n\n /// @notice return trusted forwarder address\n function getTrustedForwarder() external view returns (address) {\n return _trustedForwarder;\n }\n\n function _msgSender() internal view virtual returns (address sender) {\n if (isTrustedForwarder(msg.sender)) {\n require(msg.data.length >= 24, \"ERC2771HandlerV2: Invalid msg.data\");\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n if (isTrustedForwarder(msg.sender)) {\n require(msg.data.length >= 24, \"ERC2771HandlerV2: Invalid msg.data\");\n return msg.data[:msg.data.length - 20];\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/ERC677/extensions/ERC677Extension.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"../../../interfaces/IERC677.sol\";\nimport \"../../../interfaces/IERC677Receiver.sol\";\nimport \"../../ERC20/extensions/ERC20Internal.sol\";\nimport \"@openzeppelin/contracts-0.8/utils/Address.sol\";\nimport \"@openzeppelin/contracts-0.8/utils/Context.sol\";\n\nabstract contract ERC677Extension is ERC20Internal, IERC677, Context {\n using Address for address;\n\n /// @notice Transfers tokens to an address with _data if the recipient is a contact.\n /// @param _to The address to transfer to.\n /// @param _value The amount to be transferred.\n /// @param _data The extra data to be passed to the receiving contract.\n function transferAndCall(\n address _to,\n uint256 _value,\n bytes calldata _data\n ) external override returns (bool success) {\n _transfer(_msgSender(), _to, _value);\n if (_to.isContract()) {\n IERC677Receiver receiver = IERC677Receiver(_to);\n receiver.onTokenTransfer(_msgSender(), _value, _data);\n }\n return true;\n }\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/ERC721BaseToken.sol": { + "content": "//SPDX-License-Identifier: MIT\n/* solhint-disable func-order, code-complexity */\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"./WithSuperOperators.sol\";\nimport \"../interfaces/IERC721MandatoryTokenReceiver.sol\";\nimport \"./ERC2771Handler.sol\";\n\ncontract ERC721BaseToken is IERC721Upgradeable, WithSuperOperators, ERC2771Handler {\n using AddressUpgradeable for address;\n\n bytes4 internal constant _ERC721_RECEIVED = 0x150b7a02;\n bytes4 internal constant _ERC721_BATCH_RECEIVED = 0x4b808c46;\n\n bytes4 internal constant ERC165ID = 0x01ffc9a7;\n bytes4 internal constant ERC721_MANDATORY_RECEIVER = 0x5e8bf644;\n\n uint256 internal constant NOT_ADDRESS = 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000;\n uint256 internal constant OPERATOR_FLAG = (2**255);\n uint256 internal constant NOT_OPERATOR_FLAG = OPERATOR_FLAG - 1;\n uint256 internal constant BURNED_FLAG = (2**160);\n\n mapping(address => uint256) internal _numNFTPerAddress;\n mapping(uint256 => uint256) internal _owners;\n mapping(address => mapping(address => bool)) internal _operatorsForAll;\n mapping(uint256 => address) internal _operators;\n\n /// @notice Approve an operator to spend tokens on the senders behalf.\n /// @param operator The address receiving the approval.\n /// @param id The id of the token.\n function approve(address operator, uint256 id) external override {\n uint256 ownerData = _owners[_storageId(id)];\n address owner = _ownerOf(id);\n address msgSender = _msgSender();\n require(owner != address(0), \"NONEXISTENT_TOKEN\");\n require(\n owner == msgSender || _superOperators[msgSender] || _operatorsForAll[owner][msgSender],\n \"UNAUTHORIZED_APPROVAL\"\n );\n _approveFor(ownerData, operator, id);\n }\n\n /// @notice Approve an operator to spend tokens on the sender behalf.\n /// @param sender The address giving the approval.\n /// @param operator The address receiving the approval.\n /// @param id The id of the token.\n function approveFor(\n address sender,\n address operator,\n uint256 id\n ) external {\n uint256 ownerData = _owners[_storageId(id)];\n address owner = _ownerOf(id);\n address msgSender = _msgSender();\n require(sender != address(0), \"ZERO_ADDRESS_SENDER\");\n require(owner != address(0), \"NONEXISTENT_TOKEN\");\n require(\n msgSender == sender || _superOperators[msgSender] || _operatorsForAll[sender][msgSender],\n \"UNAUTHORIZED_APPROVAL\"\n );\n require(address(uint160(ownerData)) == sender, \"OWNER_NOT_SENDER\");\n _approveFor(ownerData, operator, id);\n }\n\n /// @notice Transfer a token between 2 addresses.\n /// @param from The sender of the token.\n /// @param to The recipient of the token.\n /// @param id The id of the token.\n function transferFrom(\n address from,\n address to,\n uint256 id\n ) external override {\n _checkTransfer(from, to, id);\n _transferFrom(from, to, id);\n if (to.isContract() && _checkInterfaceWith10000Gas(to, ERC721_MANDATORY_RECEIVER)) {\n require(_checkOnERC721Received(_msgSender(), from, to, id, \"\"), \"ERC721_TRANSFER_REJECTED\");\n }\n }\n\n /// @notice Transfer a token between 2 addresses letting the receiver know of the transfer.\n /// @param from The send of the token.\n /// @param to The recipient of the token.\n /// @param id The id of the token.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id\n ) external override {\n safeTransferFrom(from, to, id, \"\");\n }\n\n /// @notice Transfer many tokens between 2 addresses.\n /// @param from The sender of the token.\n /// @param to The recipient of the token.\n /// @param ids The ids of the tokens.\n /// @param data Additional data.\n function batchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n bytes calldata data\n ) public virtual {\n _batchTransferFrom(from, to, ids, data, false);\n }\n\n /// @notice Transfer many tokens between 2 addresses, while\n /// ensuring the receiving contract has a receiver method.\n /// @param from The sender of the token.\n /// @param to The recipient of the token.\n /// @param ids The ids of the tokens.\n /// @param data Additional data.\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n bytes calldata data\n ) external {\n _batchTransferFrom(from, to, ids, data, true);\n }\n\n /// @notice Set the approval for an operator to manage all the tokens of the sender.\n /// @param sender The address giving the approval.\n /// @param operator The address receiving the approval.\n /// @param approved The determination of the approval.\n function setApprovalForAllFor(\n address sender,\n address operator,\n bool approved\n ) external {\n require(sender != address(0), \"Invalid sender address\");\n address msgSender = _msgSender();\n require(msgSender == sender || _superOperators[msgSender], \"UNAUTHORIZED_APPROVE_FOR_ALL\");\n\n _setApprovalForAll(sender, operator, approved);\n }\n\n /// @notice Set the approval for an operator to manage all the tokens of the sender.\n /// @param operator The address receiving the approval.\n /// @param approved The determination of the approval.\n function setApprovalForAll(address operator, bool approved) external override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /// @notice Burns token `id`.\n /// @param id The token which will be burnt.\n function burn(uint256 id) external virtual {\n _burn(_msgSender(), _ownerOf(id), id);\n }\n\n /// @notice Burn token`id` from `from`.\n /// @param from address whose token is to be burnt.\n /// @param id The token which will be burnt.\n function burnFrom(address from, uint256 id) external virtual {\n require(from != address(0), \"NOT_FROM_ZEROADDRESS\");\n (address owner, bool operatorEnabled) = _ownerAndOperatorEnabledOf(id);\n address msgSender = _msgSender();\n require(\n msgSender == from ||\n (operatorEnabled && _operators[id] == msgSender) ||\n _superOperators[msgSender] ||\n _operatorsForAll[from][msgSender],\n \"UNAUTHORIZED_BURN\"\n );\n _burn(from, owner, id);\n }\n\n /// @notice Get the number of tokens owned by an address.\n /// @param owner The address to look for.\n /// @return The number of tokens owned by the address.\n function balanceOf(address owner) external view override returns (uint256) {\n require(owner != address(0), \"ZERO_ADDRESS_OWNER\");\n return _numNFTPerAddress[owner];\n }\n\n /// @notice Get the owner of a token.\n /// @param id The id of the token.\n /// @return owner The address of the token owner.\n function ownerOf(uint256 id) external view override returns (address owner) {\n owner = _ownerOf(id);\n require(owner != address(0), \"NONEXISTANT_TOKEN\");\n }\n\n /// @notice Get the approved operator for a specific token.\n /// @param id The id of the token.\n /// @return The address of the operator.\n function getApproved(uint256 id) external view override returns (address) {\n (address owner, bool operatorEnabled) = _ownerAndOperatorEnabledOf(id);\n require(owner != address(0), \"NONEXISTENT_TOKEN\");\n if (operatorEnabled) {\n return _operators[id];\n } else {\n return address(0);\n }\n }\n\n /// @notice Check if the sender approved the operator.\n /// @param owner The address of the owner.\n /// @param operator The address of the operator.\n /// @return isOperator The status of the approval.\n function isApprovedForAll(address owner, address operator) external view override returns (bool isOperator) {\n return _operatorsForAll[owner][operator] || _superOperators[operator];\n }\n\n /// @notice Transfer a token between 2 addresses letting the receiver knows of the transfer.\n /// @param from The sender of the token.\n /// @param to The recipient of the token.\n /// @param id The id of the token.\n /// @param data Additional data.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n bytes memory data\n ) public override {\n _checkTransfer(from, to, id);\n _transferFrom(from, to, id);\n if (to.isContract()) {\n require(_checkOnERC721Received(_msgSender(), from, to, id, data), \"ERC721_TRANSFER_REJECTED\");\n }\n }\n\n /// @notice Check if the contract supports an interface.\n /// 0x01ffc9a7 is ERC-165.\n /// 0x80ac58cd is ERC-721\n /// @param id The id of the interface.\n /// @return Whether the interface is supported.\n function supportsInterface(bytes4 id) public pure virtual override returns (bool) {\n return id == 0x01ffc9a7 || id == 0x80ac58cd;\n }\n\n /// @dev By overriding this function in an implementation which inherits this contract, you can enable versioned tokenIds without the extra overhead of writing to a new storage slot in _owners each time a version is incremented. See GameToken._storageId() for an example, where the storageId is the tokenId minus the version number.\n /// !!! Caution !!! Overriding this function without taking appropriate care could lead to\n /// ownerOf() returning an owner for non-existent tokens. Tests should be written to\n /// guard against introducing this bug.\n /// @param id The id of a token.\n /// @return The id used for storage mappings.\n function _storageId(uint256 id) internal view virtual returns (uint256) {\n return id;\n }\n\n function _updateOwnerData(\n uint256 id,\n uint256 oldData,\n address newOwner,\n bool hasOperator\n ) internal virtual {\n if (hasOperator) {\n _owners[_storageId(id)] = (oldData & NOT_ADDRESS) | OPERATOR_FLAG | uint256(uint160(newOwner));\n } else {\n _owners[_storageId(id)] = ((oldData & NOT_ADDRESS) & NOT_OPERATOR_FLAG) | uint256(uint160(newOwner));\n }\n }\n\n function _transferFrom(\n address from,\n address to,\n uint256 id\n ) internal {\n _numNFTPerAddress[from]--;\n _numNFTPerAddress[to]++;\n _updateOwnerData(id, _owners[_storageId(id)], to, false);\n emit Transfer(from, to, id);\n }\n\n /// @dev See approveFor.\n function _approveFor(\n uint256 ownerData,\n address operator,\n uint256 id\n ) internal {\n address owner = _ownerOf(id);\n if (operator == address(0)) {\n _updateOwnerData(id, ownerData, owner, false);\n } else {\n _updateOwnerData(id, ownerData, owner, true);\n _operators[id] = operator;\n }\n emit Approval(owner, operator, id);\n }\n\n /// @dev See batchTransferFrom.\n function _batchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n bytes memory data,\n bool safe\n ) internal {\n address msgSender = _msgSender();\n bool authorized = msgSender == from || _superOperators[msgSender] || _operatorsForAll[from][msgSender];\n\n require(from != address(0), \"NOT_FROM_ZEROADDRESS\");\n require(to != address(0), \"NOT_TO_ZEROADDRESS\");\n\n uint256 numTokens = ids.length;\n for (uint256 i = 0; i < numTokens; i++) {\n uint256 id = ids[i];\n (address owner, bool operatorEnabled) = _ownerAndOperatorEnabledOf(id);\n require(owner == from, \"BATCHTRANSFERFROM_NOT_OWNER\");\n require(authorized || (operatorEnabled && _operators[id] == msgSender), \"NOT_AUTHORIZED\");\n _updateOwnerData(id, _owners[_storageId(id)], to, false);\n emit Transfer(from, to, id);\n }\n if (from != to) {\n _numNFTPerAddress[from] -= numTokens;\n _numNFTPerAddress[to] += numTokens;\n }\n\n if (to.isContract()) {\n if (_checkInterfaceWith10000Gas(to, ERC721_MANDATORY_RECEIVER)) {\n require(_checkOnERC721BatchReceived(msgSender, from, to, ids, data), \"ERC721_BATCH_RECEIVED_REJECTED\");\n } else if (safe) {\n for (uint256 i = 0; i < numTokens; i++) {\n require(_checkOnERC721Received(msgSender, from, to, ids[i], data), \"ERC721_RECEIVED_REJECTED\");\n }\n }\n }\n }\n\n /// @dev See setApprovalForAll.\n function _setApprovalForAll(\n address sender,\n address operator,\n bool approved\n ) internal {\n require(!_superOperators[operator], \"INVALID_APPROVAL_CHANGE\");\n _operatorsForAll[sender][operator] = approved;\n\n emit ApprovalForAll(sender, operator, approved);\n }\n\n /// @dev See burn.\n function _burn(\n address from,\n address owner,\n uint256 id\n ) internal {\n require(from == owner, \"NOT_OWNER\");\n uint256 storageId = _storageId(id);\n _owners[storageId] = (_owners[storageId] & NOT_OPERATOR_FLAG) | BURNED_FLAG; // record as non owner but keep track of last owner\n _numNFTPerAddress[from]--;\n emit Transfer(from, address(0), id);\n }\n\n /// @dev Check if receiving contract accepts erc721 transfers.\n /// @param operator The address of the operator.\n /// @param from The from address, may be different from msg.sender.\n /// @param to The adddress we want to transfer to.\n /// @param tokenId The id of the token we would like to transfer.\n /// @param _data Any additional data to send with the transfer.\n /// @return Whether the expected value of 0x150b7a02 is returned.\n function _checkOnERC721Received(\n address operator,\n address from,\n address to,\n uint256 tokenId,\n bytes memory _data\n ) internal returns (bool) {\n bytes4 retval = IERC721ReceiverUpgradeable(to).onERC721Received(operator, from, tokenId, _data);\n return (retval == _ERC721_RECEIVED);\n }\n\n /// @dev Check if receiving contract accepts erc721 batch transfers.\n /// @param operator The address of the operator.\n /// @param from The from address, may be different from msg.sender.\n /// @param to The adddress we want to transfer to.\n /// @param ids The ids of the tokens we would like to transfer.\n /// @param _data Any additional data to send with the transfer.\n /// @return Whether the expected value of 0x4b808c46 is returned.\n function _checkOnERC721BatchReceived(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n bytes memory _data\n ) internal returns (bool) {\n bytes4 retval = IERC721MandatoryTokenReceiver(to).onERC721BatchReceived(operator, from, ids, _data);\n return (retval == _ERC721_BATCH_RECEIVED);\n }\n\n /// @dev See ownerOf\n function _ownerOf(uint256 id) internal view virtual returns (address) {\n uint256 data = _owners[_storageId(id)];\n if ((data & BURNED_FLAG) == BURNED_FLAG) {\n return address(0);\n }\n return address(uint160(data));\n }\n\n /// @dev Get the owner and operatorEnabled status of a token.\n /// @param id The token to query.\n /// @return owner The owner of the token.\n /// @return operatorEnabled Whether or not operators are enabled for this token.\n function _ownerAndOperatorEnabledOf(uint256 id)\n internal\n view\n virtual\n returns (address owner, bool operatorEnabled)\n {\n uint256 data = _owners[_storageId(id)];\n if ((data & BURNED_FLAG) == BURNED_FLAG) {\n owner = address(0);\n } else {\n owner = address(uint160(data));\n }\n operatorEnabled = (data & OPERATOR_FLAG) == OPERATOR_FLAG;\n }\n\n /// @dev Check whether a transfer is a meta Transaction or not.\n /// @param from The address who initiated the transfer (may differ from msg.sender).\n /// @param to The address recieving the token.\n /// @param id The token being transferred.\n /// @return isMetaTx Whether or not the transaction is a MetaTx.\n function _checkTransfer(\n address from,\n address to,\n uint256 id\n ) internal view returns (bool isMetaTx) {\n (address owner, bool operatorEnabled) = _ownerAndOperatorEnabledOf(id);\n address msgSender = _msgSender();\n require(owner != address(0), \"NONEXISTENT_TOKEN\");\n require(owner == from, \"CHECKTRANSFER_NOT_OWNER\");\n require(to != address(0), \"NOT_TO_ZEROADDRESS\");\n require(\n msgSender == owner ||\n _superOperators[msgSender] ||\n _operatorsForAll[from][msgSender] ||\n (operatorEnabled && _operators[id] == msgSender),\n \"UNAUTHORIZED_TRANSFER\"\n );\n return true;\n }\n\n /// @dev Check if there was enough gas.\n /// @param _contract The address of the contract to check.\n /// @param interfaceId The id of the interface we want to test.\n /// @return Whether or not this check succeeded.\n function _checkInterfaceWith10000Gas(address _contract, bytes4 interfaceId) internal view returns (bool) {\n bool success;\n bool result;\n bytes memory callData = abi.encodeWithSelector(ERC165ID, interfaceId);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let call_ptr := add(0x20, callData)\n let call_size := mload(callData)\n let output := mload(0x40) // Find empty storage location using \"free memory pointer\"\n mstore(output, 0x0)\n success := staticcall(10000, _contract, call_ptr, call_size, output, 0x20) // 32 bytes\n result := mload(output)\n }\n // (10000 / 63) \"not enough for supportsInterface(...)\" // consume all gas, so caller can potentially know that there was not enough gas\n assert(gasleft() > 158);\n return success && result;\n }\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/ERC721BaseTokenV2.sol": { + "content": "//SPDX-License-Identifier: MIT\n/* solhint-disable func-order, code-complexity */\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\nimport {AddressUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport {\n IERC721ReceiverUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport {IERC721Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport {WithSuperOperatorsV2} from \"./WithSuperOperatorsV2.sol\";\nimport {IERC721MandatoryTokenReceiver} from \"../interfaces/IERC721MandatoryTokenReceiver.sol\";\nimport {ContextUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\n\n/// @title ERC721BaseTokenV2\n/// @author The Sandbox\n/// @notice Basic functionalities of a NFT\n/// @dev ERC721 implementation that supports meta-transactions and super operators\ncontract ERC721BaseTokenV2 is ContextUpgradeable, IERC721Upgradeable, WithSuperOperatorsV2 {\n using AddressUpgradeable for address;\n\n bytes4 internal constant _ERC721_RECEIVED = 0x150b7a02;\n bytes4 internal constant _ERC721_BATCH_RECEIVED = 0x4b808c46;\n\n bytes4 internal constant ERC165ID = 0x01ffc9a7;\n bytes4 internal constant ERC721_MANDATORY_RECEIVER = 0x5e8bf644;\n\n uint256 internal constant NOT_ADDRESS = 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000;\n uint256 internal constant OPERATOR_FLAG = (2**255);\n uint256 internal constant NOT_OPERATOR_FLAG = OPERATOR_FLAG - 1;\n uint256 internal constant BURNED_FLAG = (2**160);\n\n mapping(address => uint256) internal _numNFTPerAddress;\n /**\n * @dev mapping to store owner of lands and quads.\n * For 1x1 lands it also the 255 bit is 1 if that land has operator approved and is 0 if no operator is approved.\n * For burned 1x1 Land 160 bit is set to 1.\n */\n mapping(uint256 => uint256) internal _owners;\n mapping(address => mapping(address => bool)) internal _operatorsForAll;\n mapping(uint256 => address) internal _operators;\n\n /// @notice Approve an operator to spend tokens on the senders behalf.\n /// @param operator The address receiving the approval.\n /// @param id The id of the token.\n function approve(address operator, uint256 id) public virtual override {\n uint256 ownerData = _owners[_storageId(id)];\n address owner = _ownerOf(id);\n address msgSender = _msgSender();\n require(owner != address(0), \"NONEXISTENT_TOKEN\");\n require(\n owner == msgSender || _operatorsForAll[owner][msgSender] || _superOperators[msgSender],\n \"UNAUTHORIZED_APPROVAL\"\n );\n _approveFor(ownerData, operator, id);\n }\n\n /// @notice Approve an operator to spend tokens on the sender behalf.\n /// @param sender The address giving the approval.\n /// @param operator The address receiving the approval.\n /// @param id The id of the token.\n function approveFor(\n address sender,\n address operator,\n uint256 id\n ) public virtual {\n uint256 ownerData = _owners[_storageId(id)];\n address owner = _ownerOf(id);\n address msgSender = _msgSender();\n require(sender != address(0), \"ZERO_ADDRESS_SENDER\");\n require(owner != address(0), \"NONEXISTENT_TOKEN\");\n require(\n msgSender == sender || _operatorsForAll[sender][msgSender] || _superOperators[msgSender],\n \"UNAUTHORIZED_APPROVAL\"\n );\n require(address(uint160(ownerData)) == sender, \"OWNER_NOT_SENDER\");\n _approveFor(ownerData, operator, id);\n }\n\n /// @notice Transfer a token between 2 addresses.\n /// @param from The sender of the token.\n /// @param to The recipient of the token.\n /// @param id The id of the token.\n function transferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual override {\n _checkTransfer(from, to, id);\n _transferFrom(from, to, id);\n if (to.isContract() && _checkInterfaceWith10000Gas(to, ERC721_MANDATORY_RECEIVER)) {\n require(_checkOnERC721Received(_msgSender(), from, to, id, \"\"), \"ERC721_TRANSFER_REJECTED\");\n }\n }\n\n /// @notice Transfer a token between 2 addresses letting the receiver know of the transfer.\n /// @param from The sender of the token.\n /// @param to The recipient of the token.\n /// @param id The id of the token.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual override {\n safeTransferFrom(from, to, id, \"\");\n }\n\n /// @notice Transfer many tokens between 2 addresses.\n /// @param from The sender of the token.\n /// @param to The recipient of the token.\n /// @param ids The ids of the tokens.\n /// @param data Additional data.\n function batchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n bytes calldata data\n ) public virtual {\n _batchTransferFrom(from, to, ids, data, false);\n }\n\n /// @notice Transfer many tokens between 2 addresses, while\n /// ensuring the receiving contract has a receiver method.\n /// @param from The sender of the token.\n /// @param to The recipient of the token.\n /// @param ids The ids of the tokens.\n /// @param data Additional data.\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n bytes calldata data\n ) external virtual {\n _batchTransferFrom(from, to, ids, data, true);\n }\n\n /// @notice Set the approval for an operator to manage all the tokens of the sender.\n /// @param sender The address giving the approval.\n /// @param operator The address receiving the approval.\n /// @param approved The determination of the approval.\n function setApprovalForAllFor(\n address sender,\n address operator,\n bool approved\n ) public virtual {\n require(sender != address(0), \"Invalid sender address\");\n address msgSender = _msgSender();\n require(msgSender == sender || _superOperators[msgSender], \"UNAUTHORIZED_APPROVE_FOR_ALL\");\n\n _setApprovalForAll(sender, operator, approved);\n }\n\n /// @notice Set the approval for an operator to manage all the tokens of the sender.\n /// @param operator The address receiving the approval.\n /// @param approved The determination of the approval.\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /// @notice Burns token `id`.\n /// @param id The token which will be burnt.\n function burn(uint256 id) external virtual {\n _burn(_msgSender(), _ownerOf(id), id);\n }\n\n /// @notice Burn token `id` from `from`.\n /// @param from address whose token is to be burnt.\n /// @param id The token which will be burnt.\n function burnFrom(address from, uint256 id) external virtual {\n require(from != address(0), \"NOT_FROM_ZEROADDRESS\");\n (address owner, bool operatorEnabled) = _ownerAndOperatorEnabledOf(id);\n address msgSender = _msgSender();\n require(\n msgSender == from ||\n (operatorEnabled && _operators[id] == msgSender) ||\n _superOperators[msgSender] ||\n _operatorsForAll[from][msgSender],\n \"UNAUTHORIZED_BURN\"\n );\n _burn(from, owner, id);\n }\n\n /// @notice Get the number of tokens owned by an address.\n /// @param owner The address to look for.\n /// @return The number of tokens owned by the address.\n function balanceOf(address owner) external view override returns (uint256) {\n require(owner != address(0), \"ZERO_ADDRESS_OWNER\");\n return _numNFTPerAddress[owner];\n }\n\n /// @notice Get the owner of a token.\n /// @param id The id of the token.\n /// @return owner The address of the token owner.\n function ownerOf(uint256 id) external view override returns (address owner) {\n owner = _ownerOf(id);\n require(owner != address(0), \"NONEXISTANT_TOKEN\");\n }\n\n /// @notice Get the approved operator for a specific token.\n /// @param id The id of the token.\n /// @return The address of the operator.\n function getApproved(uint256 id) external view override returns (address) {\n (address owner, bool operatorEnabled) = _ownerAndOperatorEnabledOf(id);\n require(owner != address(0), \"NONEXISTENT_TOKEN\");\n if (operatorEnabled) {\n return _operators[id];\n } else {\n return address(0);\n }\n }\n\n /// @notice Check if the sender approved the operator.\n /// @param owner The address of the owner.\n /// @param operator The address of the operator.\n /// @return isOperator The status of the approval.\n function isApprovedForAll(address owner, address operator) external view override returns (bool) {\n return _operatorsForAll[owner][operator] || _superOperators[operator];\n }\n\n /// @notice Transfer a token between 2 addresses letting the receiver knows of the transfer.\n /// @param from The sender of the token.\n /// @param to The recipient of the token.\n /// @param id The id of the token.\n /// @param data Additional data.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n bytes memory data\n ) public virtual override {\n _checkTransfer(from, to, id);\n _transferFrom(from, to, id);\n if (to.isContract()) {\n require(_checkOnERC721Received(_msgSender(), from, to, id, data), \"ERC721_TRANSFER_REJECTED\");\n }\n }\n\n /// @notice Check if the contract supports an interface.\n /// 0x01ffc9a7 is ERC-165.\n /// 0x80ac58cd is ERC-721\n /// @param id The id of the interface.\n /// @return Whether the interface is supported.\n function supportsInterface(bytes4 id) public pure virtual override returns (bool) {\n return id == 0x01ffc9a7 || id == 0x80ac58cd;\n }\n\n /// @dev By overriding this function in an implementation which inherits this contract,\n /// you can enable versioned tokenIds without the extra overhead of writing to a new storage slot in _owners each time a version is incremented.\n /// See GameToken._storageId() for an example, where the storageId is the tokenId minus the version number.\n /// !!! Caution !!! Overriding this function without taking appropriate care could lead to\n /// ownerOf() returning an owner for non-existent tokens. Tests should be written to\n /// guard against introducing this bug.\n /// @param id The id of a token.\n /// @return The id used for storage mappings.\n function _storageId(uint256 id) internal view virtual returns (uint256) {\n return id;\n }\n\n function _updateOwnerData(\n uint256 id,\n uint256 oldData,\n address newOwner,\n bool hasOperator\n ) internal virtual {\n if (hasOperator) {\n _owners[_storageId(id)] = (oldData & NOT_ADDRESS) | OPERATOR_FLAG | uint256(uint160(newOwner));\n } else {\n _owners[_storageId(id)] = ((oldData & NOT_ADDRESS) & NOT_OPERATOR_FLAG) | uint256(uint160(newOwner));\n }\n }\n\n function _transferFrom(\n address from,\n address to,\n uint256 id\n ) internal {\n _numNFTPerAddress[from]--;\n _numNFTPerAddress[to]++;\n _updateOwnerData(id, _owners[_storageId(id)], to, false);\n emit Transfer(from, to, id);\n }\n\n /// @dev See approveFor.\n function _approveFor(\n uint256 ownerData,\n address operator,\n uint256 id\n ) internal {\n address owner = _ownerOf(id);\n if (operator == address(0)) {\n _updateOwnerData(id, ownerData, owner, false);\n } else {\n _updateOwnerData(id, ownerData, owner, true);\n _operators[id] = operator;\n }\n emit Approval(owner, operator, id);\n }\n\n /// @dev See batchTransferFrom.\n function _batchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n bytes memory data,\n bool safe\n ) internal {\n address msgSender = _msgSender();\n bool authorized = msgSender == from || _operatorsForAll[from][msgSender] || _superOperators[msgSender];\n\n require(from != address(0), \"NOT_FROM_ZEROADDRESS\");\n require(to != address(0), \"NOT_TO_ZEROADDRESS\");\n\n uint256 numTokens = ids.length;\n for (uint256 i = 0; i < numTokens; i++) {\n uint256 id = ids[i];\n (address owner, bool operatorEnabled) = _ownerAndOperatorEnabledOf(id);\n require(owner == from, \"BATCHTRANSFERFROM_NOT_OWNER\");\n require(authorized || (operatorEnabled && _operators[id] == msgSender), \"NOT_AUTHORIZED\");\n _updateOwnerData(id, _owners[_storageId(id)], to, false);\n emit Transfer(from, to, id);\n }\n if (from != to) {\n _numNFTPerAddress[from] -= numTokens;\n _numNFTPerAddress[to] += numTokens;\n }\n\n if (to.isContract()) {\n if (_checkInterfaceWith10000Gas(to, ERC721_MANDATORY_RECEIVER)) {\n require(_checkOnERC721BatchReceived(msgSender, from, to, ids, data), \"ERC721_BATCH_RECEIVED_REJECTED\");\n } else if (safe) {\n for (uint256 i = 0; i < numTokens; i++) {\n require(_checkOnERC721Received(msgSender, from, to, ids[i], data), \"ERC721_RECEIVED_REJECTED\");\n }\n }\n }\n }\n\n /// @dev See setApprovalForAll.\n function _setApprovalForAll(\n address sender,\n address operator,\n bool approved\n ) internal {\n require(!_superOperators[operator], \"INVALID_APPROVAL_CHANGE\");\n _operatorsForAll[sender][operator] = approved;\n\n emit ApprovalForAll(sender, operator, approved);\n }\n\n /// @dev See burn.\n function _burn(\n address from,\n address owner,\n uint256 id\n ) internal {\n require(from == owner, \"NOT_OWNER\");\n uint256 storageId = _storageId(id);\n _owners[storageId] = (_owners[storageId] & NOT_OPERATOR_FLAG) | BURNED_FLAG; // record as non owner but keep track of last owner\n _numNFTPerAddress[from]--;\n emit Transfer(from, address(0), id);\n }\n\n /// @dev Check if receiving contract accepts erc721 transfers.\n /// @param operator The address of the operator.\n /// @param from The from address, may be different from msg.sender.\n /// @param to The address we want to transfer to.\n /// @param tokenId The id of the token we would like to transfer.\n /// @param _data Any additional data to send with the transfer.\n /// @return Whether the expected value of 0x150b7a02 is returned.\n function _checkOnERC721Received(\n address operator,\n address from,\n address to,\n uint256 tokenId,\n bytes memory _data\n ) internal returns (bool) {\n bytes4 retval = IERC721ReceiverUpgradeable(to).onERC721Received(operator, from, tokenId, _data);\n return (retval == _ERC721_RECEIVED);\n }\n\n /// @dev Check if receiving contract accepts erc721 batch transfers.\n /// @param operator The address of the operator.\n /// @param from The from address, may be different from msg.sender.\n /// @param to The address we want to transfer to.\n /// @param ids The ids of the tokens we would like to transfer.\n /// @param _data Any additional data to send with the transfer.\n /// @return Whether the expected value of 0x4b808c46 is returned.\n function _checkOnERC721BatchReceived(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n bytes memory _data\n ) internal returns (bool) {\n bytes4 retval = IERC721MandatoryTokenReceiver(to).onERC721BatchReceived(operator, from, ids, _data);\n return (retval == _ERC721_BATCH_RECEIVED);\n }\n\n /// @dev See ownerOf\n function _ownerOf(uint256 id) internal view virtual returns (address) {\n uint256 data = _owners[_storageId(id)];\n if ((data & BURNED_FLAG) == BURNED_FLAG) {\n return address(0);\n }\n return address(uint160(data));\n }\n\n /// @dev Get the owner and operatorEnabled status of a token.\n /// @param id The token to query.\n /// @return owner The owner of the token.\n /// @return operatorEnabled Whether or not operators are enabled for this token.\n function _ownerAndOperatorEnabledOf(uint256 id)\n internal\n view\n virtual\n returns (address owner, bool operatorEnabled)\n {\n uint256 data = _owners[_storageId(id)];\n if ((data & BURNED_FLAG) == BURNED_FLAG) {\n owner = address(0);\n } else {\n owner = address(uint160(data));\n }\n operatorEnabled = (data & OPERATOR_FLAG) == OPERATOR_FLAG;\n }\n\n /// @dev Check whether a transfer is a meta Transaction or not.\n /// @param from The address who initiated the transfer (may differ from msg.sender).\n /// @param to The address receiving the token.\n /// @param id The token being transferred.\n function _checkTransfer(\n address from,\n address to,\n uint256 id\n ) internal view {\n (address owner, bool operatorEnabled) = _ownerAndOperatorEnabledOf(id);\n address msgSender = _msgSender();\n require(owner != address(0), \"NONEXISTENT_TOKEN\");\n require(owner == from, \"CHECKTRANSFER_NOT_OWNER\");\n require(to != address(0), \"NOT_TO_ZEROADDRESS\");\n require(\n msgSender == owner ||\n _superOperators[msgSender] ||\n _operatorsForAll[from][msgSender] ||\n (operatorEnabled && _operators[id] == msgSender),\n \"UNAUTHORIZED_TRANSFER\"\n );\n }\n\n /// @dev Check if there was enough gas.\n /// @param _contract The address of the contract to check.\n /// @param interfaceId The id of the interface we want to test.\n /// @return Whether or not this check succeeded.\n function _checkInterfaceWith10000Gas(address _contract, bytes4 interfaceId) internal view returns (bool) {\n bool success;\n bool result;\n bytes memory callData = abi.encodeWithSelector(ERC165ID, interfaceId);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let call_ptr := add(0x20, callData)\n let call_size := mload(callData)\n let output := mload(0x40) // Find empty storage location using \"free memory pointer\"\n mstore(output, 0x0)\n success := staticcall(10000, _contract, call_ptr, call_size, output, 0x20) // 32 bytes\n result := mload(output)\n }\n // (10000 / 63) \"not enough for supportsInterface(...)\" // consume all gas, so caller can potentially know that there was not enough gas\n assert(gasleft() > 158);\n return success && result;\n }\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/MetaTransactionReceiver.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"./WithAdmin.sol\";\n\ncontract MetaTransactionReceiver is WithAdmin {\n mapping(address => bool) internal _metaTransactionContracts;\n event MetaTransactionProcessor(address metaTransactionProcessor, bool enabled);\n\n /// @notice Enable or disable the ability of `metaTransactionProcessor` to perform meta-tx (metaTransactionProcessor rights).\n /// @param metaTransactionProcessor address that will be given/removed metaTransactionProcessor rights.\n /// @param enabled set whether the metaTransactionProcessor is enabled or disabled.\n function setMetaTransactionProcessor(address metaTransactionProcessor, bool enabled) external {\n require(msg.sender == _admin, \"only admin can setup metaTransactionProcessors\");\n _setMetaTransactionProcessor(metaTransactionProcessor, enabled);\n }\n\n function _setMetaTransactionProcessor(address metaTransactionProcessor, bool enabled) internal {\n _metaTransactionContracts[metaTransactionProcessor] = enabled;\n emit MetaTransactionProcessor(metaTransactionProcessor, enabled);\n }\n\n /// @notice check whether address `who` is given meta-transaction execution rights.\n /// @param who The address to query.\n /// @return whether the address has meta-transaction execution rights.\n function isMetaTransactionProcessor(address who) external view returns (bool) {\n return _metaTransactionContracts[who];\n }\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/WithAdmin.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\ncontract WithAdmin {\n address internal _admin;\n\n /// @dev Emits when the contract administrator is changed.\n /// @param oldAdmin The address of the previous administrator.\n /// @param newAdmin The address of the new administrator.\n event AdminChanged(address indexed oldAdmin, address indexed newAdmin);\n\n modifier onlyAdmin() {\n require(msg.sender == _admin, \"ADMIN_ONLY\");\n _;\n }\n\n /// @dev Get the current administrator of this contract.\n /// @return The current administrator of this contract.\n function getAdmin() external view returns (address) {\n return _admin;\n }\n\n /// @dev Change the administrator to be `newAdmin`.\n /// @param newAdmin The address of the new administrator.\n function changeAdmin(address newAdmin) external {\n require(msg.sender == _admin, \"ADMIN_ACCESS_DENIED\");\n emit AdminChanged(_admin, newAdmin);\n _admin = newAdmin;\n }\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/WithAdminV2.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\nimport {ContextUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\n\n/// @title WithAdminV2\n/// @author The Sandbox\n/// @notice Add an admin to the contract\ncontract WithAdminV2 is ContextUpgradeable {\n address internal _admin;\n\n /// @dev Emits when the contract administrator is changed.\n /// @param oldAdmin The address of the previous administrator.\n /// @param newAdmin The address of the new administrator.\n event AdminChanged(address indexed oldAdmin, address indexed newAdmin);\n\n modifier onlyAdmin() {\n require(_msgSender() == _admin, \"ADMIN_ONLY\");\n _;\n }\n\n /// @notice Get the current admin\n /// @dev Get the current administrator of this contract.\n /// @return The current administrator of this contract.\n function getAdmin() external view returns (address) {\n return _admin;\n }\n\n /// @notice Change the admin of the contract\n /// @dev Change the administrator to be `newAdmin`.\n /// @param newAdmin The address of the new administrator.\n function changeAdmin(address newAdmin) external {\n address admin = _admin;\n require(_msgSender() == admin, \"ADMIN_ACCESS_DENIED\");\n emit AdminChanged(admin, newAdmin);\n _admin = newAdmin;\n }\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/WithPermit.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/token/ERC20/extensions/draft-IERC20Permit.sol\";\nimport \"../../common/interfaces/IERC20Extended.sol\";\nimport \"../../common/Base/TheSandbox712.sol\";\n\n/// @title Permit contract\n/// @notice This contract manages approvals of SAND via signature\nabstract contract WithPermit is TheSandbox712, IERC20Permit {\n mapping(address => uint256) public _nonces;\n\n bytes32 public constant PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n\n /// @notice Function to permit the expenditure of ERC20 token by a nominated spender\n /// @param owner The owner of the ERC20 tokens\n /// @param spender The nominated spender of the ERC20 tokens\n /// @param value The value (allowance) of the ERC20 tokens that the nominated spender will be allowed to spend\n /// @param deadline The deadline for granting permission to the spender\n /// @param v The final 1 byte of signature\n /// @param r The first 32 bytes of signature\n /// @param s The second 32 bytes of signature\n function checkApproveFor(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public {\n require(deadline >= block.timestamp, \"PAST_DEADLINE\");\n bytes32 digest =\n keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _DOMAIN_SEPARATOR,\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, _nonces[owner]++, deadline))\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNATURE\");\n }\n\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _DOMAIN_SEPARATOR;\n }\n\n function nonces(address owner) external view override returns (uint256) {\n return _nonces[owner];\n }\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/WithPermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\";\n\nabstract contract WithPermitUpgradeable is EIP712Upgradeable, IERC20PermitUpgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 public constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n\n function __WithPermitUpgradeable_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n /// @notice Function to permit the expenditure of ERC20 token by a nominated spender\n /// @param owner The owner of the ERC20 tokens\n /// @param spender The nominated spender of the ERC20 tokens\n /// @param value The value (allowance) of the ERC20 tokens that the nominated spender will be allowed to spend\n /// @param deadline The deadline for granting permission to the spender\n /// @param v The final 1 byte of signature\n /// @param r The first 32 bytes of signature\n /// @param s The second 32 bytes of signature\n function checkApproveFor(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public {\n require(block.timestamp <= deadline, \"PAST_DEADLINE\");\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n bytes32 hash = _hashTypedDataV4(structHash);\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"INVALID_SIGNATURE\");\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n function nonces(address owner) external view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/WithSuperOperators.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\nimport \"./WithAdmin.sol\";\n\ncontract WithSuperOperators is WithAdmin {\n mapping(address => bool) internal _superOperators;\n\n event SuperOperator(address indexed superOperator, bool indexed enabled);\n\n /// @notice Enable or disable the ability of `superOperator` to transfer tokens of all (superOperator rights).\n /// @param superOperator address that will be given/removed superOperator right.\n /// @param enabled set whether the superOperator is enabled or disabled.\n function setSuperOperator(address superOperator, bool enabled) external {\n require(msg.sender == _admin, \"only admin is allowed to add super operators\");\n _superOperators[superOperator] = enabled;\n emit SuperOperator(superOperator, enabled);\n }\n\n /// @notice check whether address `who` is given superOperator rights.\n /// @param who The address to query.\n /// @return whether the address has superOperator rights.\n function isSuperOperator(address who) public view returns (bool) {\n return _superOperators[who];\n }\n}\n" + }, + "src/solc_0.8/common/BaseWithStorage/WithSuperOperatorsV2.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\nimport {WithAdminV2} from \"./WithAdminV2.sol\";\nimport {ContextUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\n\n/// @title WithSuperOperatorsV2\n/// @author The Sandbox\n/// @notice Add super operators handled by an admin\ncontract WithSuperOperatorsV2 is ContextUpgradeable, WithAdminV2 {\n mapping(address => bool) internal _superOperators;\n\n event SuperOperator(address indexed superOperator, bool indexed enabled);\n\n /// @notice Enable or disable the ability of `superOperator` to transfer tokens of all (superOperator rights).\n /// @param superOperator address that will be given/removed superOperator right.\n /// @param enabled set whether the superOperator is enabled or disabled.\n function setSuperOperator(address superOperator, bool enabled) external onlyAdmin {\n require(_msgSender() == _admin, \"only admin is allowed to add super operators\");\n _superOperators[superOperator] = enabled;\n emit SuperOperator(superOperator, enabled);\n }\n\n /// @notice check whether address `who` is given superOperator rights.\n /// @param who The address to query.\n /// @return whether the address has superOperator rights.\n function isSuperOperator(address who) public view returns (bool) {\n return _superOperators[who];\n }\n}\n" + }, + "src/solc_0.8/common/fx-portal/FxBaseChildTunnelUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {FxBaseChildTunnel} from \"@maticnetwork/fx-portal/contracts/tunnel/FxBaseChildTunnel.sol\";\n\n/**\n * @title FxBaseChildTunnelUpgradeable\n * @author The Sandbox\n * @dev Upgradeable version of the fx-portal tunnel for the child chain\n */\nabstract contract FxBaseChildTunnelUpgradeable is FxBaseChildTunnel {\n // solhint-disable-next-line no-empty-blocks\n constructor() FxBaseChildTunnel(address(0)) {}\n\n /**\n * @dev Initializes the contract\n * @param _fxChild fx child\n */\n function __FxBaseChildTunnelUpgradeable_initialize(address _fxChild) internal {\n fxChild = _fxChild;\n }\n\n uint256[50] private __gap;\n}\n" + }, + "src/solc_0.8/common/fx-portal/FxBaseRootTunnelUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {\n FxBaseRootTunnel,\n ICheckpointManager,\n IFxStateSender\n} from \"@maticnetwork/fx-portal/contracts/tunnel/FxBaseRootTunnel.sol\";\n\n/**\n * @title FxBaseRootTunnelUpgradeable\n * @author The Sandbox\n * @dev Upgradeable version of the fx-portal tunnel for the root chain\n */\nabstract contract FxBaseRootTunnelUpgradeable is FxBaseRootTunnel {\n // solhint-disable-next-line no-empty-blocks\n constructor() FxBaseRootTunnel(address(0), address(0)) {}\n\n /**\n * @dev Initializes the contract\n * @param _checkpointManager checkpoint manager address\n * @param _fxRoot state sender contract\n */\n function __FxBaseRootTunnelUpgradeable_initialize(address _checkpointManager, address _fxRoot) internal {\n checkpointManager = ICheckpointManager(_checkpointManager);\n fxRoot = IFxStateSender(_fxRoot);\n }\n\n uint256[50] private __gap;\n}\n" + }, + "src/solc_0.8/common/interfaces/ERC1271.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\ninterface ERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param data Arbitrary length data signed on the behalf of address(this)\n * @param signature Signature byte array associated with _data\n *\n * MUST return the bytes4 magic value 0x20c13b0b when function passes.\n * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)\n * MUST allow external calls\n */\n function isValidSignature(bytes memory data, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "src/solc_0.8/common/interfaces/ERC1271Constants.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\ncontract ERC1271Constants {\n bytes4 internal constant ERC1271_MAGICVALUE = 0x20c13b0b;\n}\n" + }, + "src/solc_0.8/common/interfaces/ERC1654.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\ninterface ERC1654 {\n /**\n * @dev Should return whether the signature provided is valid for the provided hash\n * @param hash 32 bytes hash to be signed\n * @param signature Signature byte array associated with hash\n * @return magicValue - 0x1626ba7e if valid else 0x00000000\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "src/solc_0.8/common/interfaces/ERC1654Constants.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\ncontract ERC1654Constants {\n bytes4 internal constant ERC1654_MAGICVALUE = 0x1626ba7e;\n}\n" + }, + "src/solc_0.8/common/interfaces/IAssetAttributesRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\npragma experimental ABIEncoderV2;\n\ninterface IAssetAttributesRegistry {\n struct GemEvent {\n uint16[] gemIds;\n bytes32 blockHash;\n }\n\n struct AssetGemsCatalystData {\n uint256 assetId;\n uint16 catalystContractId;\n uint16[] gemContractIds;\n }\n\n function getRecord(uint256 assetId)\n external\n view\n returns (\n bool exists,\n uint16 catalystId,\n uint16[] memory gemIds\n );\n\n function getAttributes(uint256 assetId, GemEvent[] calldata events) external view returns (uint32[] memory values);\n\n function setCatalyst(\n uint256 assetId,\n uint16 catalystId,\n uint16[] calldata gemIds\n ) external;\n\n function setCatalystWhenDepositOnOtherLayer(\n uint256 assetId,\n uint16 catalystId,\n uint16[] calldata gemIds\n ) external;\n\n function setCatalystWithBlockNumber(\n uint256 assetId,\n uint16 catalystId,\n uint16[] calldata gemIds,\n uint64 blockNumber\n ) external;\n\n function addGems(uint256 assetId, uint16[] calldata gemIds) external;\n\n function setMigrationContract(address _migrationContract) external;\n\n function getCatalystRegistry() external view returns (address);\n}\n" + }, + "src/solc_0.8/common/interfaces/IAssetERC1155.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {IAssetERC721} from \"./IAssetERC721.sol\";\n\ninterface IAssetERC1155 {\n function changeBouncerAdmin(address newBouncerAdmin) external;\n\n function setBouncer(address bouncer, bool enabled) external;\n\n function setPredicate(address predicate) external;\n\n function mint(\n address creator,\n uint40 packId,\n bytes32 hash,\n uint256 supply,\n uint8 rarity,\n address owner,\n bytes calldata data\n ) external returns (uint256 id);\n\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n function mintMultiple(\n address account,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n\n // for bridging, where the ID has already been minted on that layer\n function mintDeficit(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n // fails on non-NFT or nft who do not have collection (was a mistake)\n function collectionOf(uint256 id) external view returns (uint256);\n\n function balanceOf(address owner, uint256 id) external view returns (uint256);\n\n // return true for Non-NFT ERC1155 tokens which exists\n function isCollection(uint256 id) external view returns (bool);\n\n function collectionIndexOf(uint256 id) external view returns (uint256);\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external;\n\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external;\n\n function burnFrom(\n address from,\n uint256 id,\n uint256 amount\n ) external;\n\n function getBouncerAdmin() external view returns (address);\n\n function extractERC721From(\n address sender,\n uint256 id,\n address to\n ) external returns (uint256 newId);\n\n function isBouncer(address who) external view returns (bool);\n\n function creatorOf(uint256 id) external view returns (address);\n\n function doesHashExist(uint256 id) external view returns (bool);\n\n function isSuperOperator(address who) external view returns (bool);\n\n function isApprovedForAll(address owner, address operator) external view returns (bool isOperator);\n\n function setApprovalForAllFor(\n address sender,\n address operator,\n bool approved\n ) external;\n\n function setApprovalForAll(address operator, bool approved) external;\n\n function balanceOfBatch(address[] calldata owners, uint256[] calldata ids) external returns (uint256[] memory);\n\n function name() external returns (string memory _name);\n\n function symbol() external returns (string memory _symbol);\n\n function supportsInterface(bytes4 id) external returns (bool);\n\n function uri(uint256 id) external returns (string memory);\n\n function setAssetERC721(IAssetERC721 assetERC721) external;\n\n function exists(uint256 tokenId) external view returns (bool);\n\n function setTrustedForwarder(address trustedForwarder) external;\n\n function isTrustedForwarder(address forwarder) external returns (bool);\n\n function getTrustedForwarder() external view returns (address);\n\n function metadataHash(uint256 id) external view returns (bytes32);\n}\n" + }, + "src/solc_0.8/common/interfaces/IAssetERC721.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {IERC721Base} from \"./IERC721Base.sol\";\n\ninterface IAssetERC721 is IERC721Base {\n function setTokenURI(uint256 id, string memory uri) external;\n\n function tokenURI(uint256 id) external view returns (string memory);\n}\n" + }, + "src/solc_0.8/common/interfaces/IAssetMinter.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\npragma experimental ABIEncoderV2;\n\ninterface IAssetMinter {\n struct AssetData {\n uint16[] gemIds;\n uint16 catalystId;\n }\n\n // use only to fix stack too deep\n struct MintData {\n address from;\n address to;\n uint40 packId;\n bytes32 metadataHash;\n bytes data;\n }\n\n function mintWithoutCatalyst(\n MintData calldata mintData,\n uint16 typeAsset1Based,\n uint256 quantity\n ) external returns (uint256 assetId);\n\n function mintWithCatalyst(\n MintData calldata mintData,\n uint16 catalystId,\n uint16[] calldata gemIds,\n uint256 quantity,\n uint256 _numberOfCatalystBurnPerAsset,\n uint256 _numberOfGemsBurnPerAsset\n ) external returns (uint256 assetId);\n\n function mintMultipleWithCatalyst(\n MintData calldata mintData,\n AssetData[] memory assets,\n uint256[] memory supplies,\n uint256 _numberOfCatalystBurnPerAsset,\n uint256 _numberOfGemsBurnPerAsset\n ) external returns (uint256[] memory assetIds);\n\n function mintMultipleWithoutCatalyst(\n MintData calldata mintData,\n uint256[] calldata supplies,\n uint16[] calldata assetTypesIds\n ) external returns (uint256[] memory assetIds);\n\n function mintCustomNumberWithCatalyst(\n MintData calldata mintData,\n uint16 catalystId,\n uint16[] calldata gemIds,\n uint256 quantity,\n uint256 _numberOfCatalystBurnPerAsset,\n uint256 _numberOfGemsBurnPerAsset\n ) external returns (uint256 assetId);\n\n function mintCustomNumberWithoutCatalyst(MintData calldata mintData, uint256 quantity)\n external\n returns (uint256 assetId);\n\n function addOrReplaceQuantityByCatalystId(uint16 catalystId, uint256 newQuantity) external;\n\n function addOrReplaceAssetTypeQuantity(uint16 index1Based, uint256 newQuantity) external;\n\n function setNumberOfGemsBurnPerAsset(uint32 newQuantity) external;\n\n function setNumberOfCatalystsBurnPerAsset(uint32 newQuantity) external;\n\n function setCustomMintingAllowance(address addressToModify, bool isAddressAllowed) external;\n}\n" + }, + "src/solc_0.8/common/interfaces/IAssetToken.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\ninterface IAssetToken {\n function mint(\n address creator,\n uint40 packId,\n bytes32 hash,\n uint256 supply,\n uint8 rarity,\n address owner,\n bytes calldata data\n ) external returns (uint256 id);\n\n function mintMultiple(\n address creator,\n uint40 packId,\n bytes32 hash,\n uint256[] calldata supplies,\n bytes calldata rarityPack,\n address owner,\n bytes calldata data\n ) external returns (uint256[] memory ids);\n\n // fails on non-NFT or nft who do not have collection (was a mistake)\n function collectionOf(uint256 id) external view returns (uint256);\n\n function balanceOf(address owner, uint256 id) external view returns (uint256);\n\n // return true for Non-NFT ERC1155 tokens which exists\n function isCollection(uint256 id) external view returns (bool);\n\n function collectionIndexOf(uint256 id) external view returns (uint256);\n\n function extractERC721From(\n address sender,\n uint256 id,\n address to\n ) external returns (uint256 newId);\n\n function transferFrom(\n address from,\n address to,\n uint256 id\n ) external;\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id\n ) external;\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external;\n\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n bytes calldata data\n ) external;\n\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external;\n\n function isSuperOperator(address who) external view returns (bool);\n}\n" + }, + "src/solc_0.8/common/interfaces/IAssetUpgrader.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\npragma experimental ABIEncoderV2;\n\ninterface IAssetUpgrader {\n function extractAndSetCatalyst(\n address from,\n uint256 assetId,\n uint16 catalystId,\n uint16[] calldata gemIds,\n address to\n ) external returns (uint256 tokenId);\n\n function changeCatalyst(\n address from,\n uint256 assetId,\n uint16 catalystId,\n uint16[] calldata gemIds,\n address to\n ) external returns (uint256 tokenId);\n\n function addGems(\n address from,\n uint256 assetId,\n uint16[] calldata gemIds,\n address to\n ) external;\n}\n" + }, + "src/solc_0.8/common/interfaces/IAttributes.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IAssetAttributesRegistry.sol\";\n\ninterface IAttributes {\n function getAttributes(uint256 assetId, IAssetAttributesRegistry.GemEvent[] calldata events)\n external\n view\n returns (uint32[] memory values);\n}\n" + }, + "src/solc_0.8/common/interfaces/IAuthValidator.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\ninterface IAuthValidator {\n function isAuthValid(bytes calldata signature, bytes32 hashedData) external view returns (bool);\n}\n" + }, + "src/solc_0.8/common/interfaces/IERC1155.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\n/**\n @title ERC-1155 Multi Token Standard\n @dev See https://eips.ethereum.org/EIPS/eip-1155\n Note: The ERC-165 identifier for this interface is 0xd9b67a26.\n */\ninterface IERC1155 {\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n event URI(string value, uint256 indexed id);\n\n /**\n @notice Transfers `value` amount of an `id` from `from` to `to` (with safety call).\n @dev Caller must be approved to manage the tokens being transferred out of the `from` account (see \"Approval\" section of the standard).\n MUST revert if `to` is the zero address.\n MUST revert if balance of holder for token `id` is lower than the `value` sent.\n MUST revert on any other error.\n MUST emit the `TransferSingle` event to reflect the balance change (see \"Safe Transfer Rules\" section of the standard).\n After the above conditions are met, this function MUST check if `to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `to` and act appropriately (see \"Safe Transfer Rules\" section of the standard).\n @param from Source address\n @param to Target address\n @param id ID of the token type\n @param value Transfer amount\n @param data Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `to`\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external;\n\n /**\n @notice Transfers `values` amount(s) of `ids` from the `from` address to the `to` address specified (with safety call).\n @dev Caller must be approved to manage the tokens being transferred out of the `from` account (see \"Approval\" section of the standard).\n MUST revert if `to` is the zero address.\n MUST revert if length of `ids` is not the same as length of `values`.\n MUST revert if any of the balance(s) of the holder(s) for token(s) in `ids` is lower than the respective amount(s) in `values` sent to the recipient.\n MUST revert on any other error.\n MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see \"Safe Transfer Rules\" section of the standard).\n Balance changes and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc).\n After the above conditions for the transfer(s) in the batch are met, this function MUST check if `to` is a smart contract (e.g. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `to` and act appropriately (see \"Safe Transfer Rules\" section of the standard).\n @param from Source address\n @param to Target address\n @param ids IDs of each token type (order and length must match _values array)\n @param values Transfer amounts per token type (order and length must match _ids array)\n @param data Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `to`\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external;\n\n /**\n @notice Get the balance of an account's tokens.\n @param owner The address of the token holder\n @param id ID of the token\n @return The _owner's balance of the token type requested\n */\n function balanceOf(address owner, uint256 id) external view returns (uint256);\n\n /**\n @notice Get the balance of multiple account/token pairs\n @param owners The addresses of the token holders\n @param ids ID of the tokens\n @return The _owner's balance of the token types requested (i.e. balance for each (owner, id) pair)\n */\n function balanceOfBatch(address[] calldata owners, uint256[] calldata ids) external view returns (uint256[] memory);\n\n /**\n @notice Enable or disable approval for a third party (\"operator\") to manage all of the caller's tokens.\n @dev MUST emit the ApprovalForAll event on success.\n @param operator Address to add to the set of authorized operators\n @param approved True if the operator is approved, false to revoke approval\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n @notice Queries the approval status of an operator for a given owner.\n @param owner The owner of the tokens\n @param operator Address of authorized operator\n @return True if the operator is approved, false if not\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "src/solc_0.8/common/interfaces/IERC1155TokenReceiver.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\n/**\n Note: The ERC-165 identifier for this interface is 0x4e2312e0.\n*/\ninterface IERC1155TokenReceiver {\n /**\n @notice Handle the receipt of a single ERC1155 token type.\n @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated.\n This function MUST return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` (i.e. 0xf23a6e61) if it accepts the transfer.\n This function MUST revert if it rejects the transfer.\n Return of any other value than the prescribed keccak256 generated value MUST result in the transaction being reverted by the caller.\n @param operator The address which initiated the transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param id The ID of the token being transferred\n @param value The amount of tokens being transferred\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n @notice Handle the receipt of multiple ERC1155 token types.\n @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated.\n This function MUST return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` (i.e. 0xbc197c81) if it accepts the transfer(s).\n This function MUST revert if it rejects the transfer(s).\n Return of any other value than the prescribed keccak256 generated value MUST result in the transaction being reverted by the caller.\n @param operator The address which initiated the batch transfer (i.e. msg.sender)\n @param from The address which previously owned the token\n @param ids An array containing ids of each token being transferred (order and length must match _values array)\n @param values An array containing amounts of each token being transferred (order and length must match _ids array)\n @param data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "src/solc_0.8/common/interfaces/IERC165.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\n/**\n * @title ERC165\n * @dev https://eips.ethereum.org/EIPS/eip-165\n */\ninterface IERC165 {\n /**\n * @notice Query if a contract implements interface `interfaceId`\n * @param interfaceId The interface identifier, as specified in ERC-165\n * @dev Interface identification is specified in ERC-165. This function\n * uses less than 30,000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "src/solc_0.8/common/interfaces/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\n/// @dev see https://eips.ethereum.org/EIPS/eip-20\ninterface IERC20 {\n /// @notice emitted when tokens are transfered from one address to another.\n /// @param from address from which the token are transfered from (zero means tokens are minted).\n /// @param to destination address which the token are transfered to (zero means tokens are burnt).\n /// @param value amount of tokens transferred.\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /// @notice emitted when owner grant transfer rights to another address\n /// @param owner address allowing its token to be transferred.\n /// @param spender address allowed to spend on behalf of `owner`\n /// @param value amount of tokens allowed.\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /// @notice return the current total amount of tokens owned by all holders.\n /// @return supply total number of tokens held.\n function totalSupply() external view returns (uint256 supply);\n\n /// @notice return the number of tokens held by a particular address.\n /// @param who address being queried.\n /// @return balance number of token held by that address.\n function balanceOf(address who) external view returns (uint256 balance);\n\n /// @notice transfer tokens to a specific address.\n /// @param to destination address receiving the tokens.\n /// @param value number of tokens to transfer.\n /// @return success whether the transfer succeeded.\n function transfer(address to, uint256 value) external returns (bool success);\n\n /// @notice transfer tokens from one address to another.\n /// @param from address tokens will be sent from.\n /// @param to destination address receiving the tokens.\n /// @param value number of tokens to transfer.\n /// @return success whether the transfer succeeded.\n function transferFrom(\n address from,\n address to,\n uint256 value\n ) external returns (bool success);\n\n /// @notice approve an address to spend on your behalf.\n /// @param spender address entitled to transfer on your behalf.\n /// @param value amount allowed to be transfered.\n /// @param success whether the approval succeeded.\n function approve(address spender, uint256 value) external returns (bool success);\n\n /// @notice return the current allowance for a particular owner/spender pair.\n /// @param owner address allowing spender.\n /// @param spender address allowed to spend.\n /// @return amount number of tokens `spender` can spend on behalf of `owner`.\n function allowance(address owner, address spender) external view returns (uint256 amount);\n}\n" + }, + "src/solc_0.8/common/interfaces/IERC20Extended.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport \"./IERC20.sol\";\n\ninterface IERC20Extended is IERC20 {\n function burnFor(address from, uint256 amount) external;\n\n function burn(uint256 amount) external;\n\n function approveFor(\n address owner,\n address spender,\n uint256 amount\n ) external returns (bool success);\n}\n" + }, + "src/solc_0.8/common/interfaces/IERC677.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\ninterface IERC677 {\n function transferAndCall(\n address to,\n uint256 value,\n bytes calldata data\n ) external returns (bool success);\n}\n" + }, + "src/solc_0.8/common/interfaces/IERC677Receiver.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address _sender,\n uint256 _value,\n bytes calldata _data\n ) external;\n}\n" + }, + "src/solc_0.8/common/interfaces/IERC721.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\nimport \"./IERC165.sol\";\nimport \"./IERC721Events.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic interface\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\n/*interface*/\ninterface IERC721 is IERC165, IERC721Events {\n function balanceOf(address owner) external view returns (uint256 balance);\n\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n // function exists(uint256 tokenId) external view returns (bool exists);\n\n function approve(address to, uint256 tokenId) external;\n\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n function setApprovalForAll(address operator, bool approved) external;\n\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n}\n" + }, + "src/solc_0.8/common/interfaces/IERC721Base.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {IERC721Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport {IERC721ExtendedToken} from \"./IERC721ExtendedToken.sol\";\n\ninterface IERC721Base is IERC721Upgradeable {\n function mint(address to, uint256 id) external;\n\n function mint(\n address to,\n uint256 id,\n bytes calldata metaData\n ) external;\n\n function approveFor(\n address from,\n address operator,\n uint256 id\n ) external;\n\n function setApprovalForAllFor(\n address from,\n address operator,\n bool approved\n ) external;\n\n function burnFrom(address from, uint256 id) external;\n\n function burn(uint256 id) external;\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external override;\n\n function batchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids\n ) external;\n\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n bytes calldata data\n ) external;\n\n function exists(uint256 tokenId) external view returns (bool);\n\n function supportsInterface(bytes4 id) external view override returns (bool);\n\n function setTrustedForwarder(address trustedForwarder) external;\n\n function isTrustedForwarder(address forwarder) external returns (bool);\n\n function getTrustedForwarder() external returns (address trustedForwarder);\n}\n" + }, + "src/solc_0.8/common/interfaces/IERC721Events.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic interface\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Events {\n event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);\n event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);\n // Duplicate event, ERC1155 ApprovalForAll\n // event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);\n}\n" + }, + "src/solc_0.8/common/interfaces/IERC721Extended.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/token/ERC721/IERC721.sol\";\n\ninterface IERC721Extended is IERC721 {\n function approveFor(\n address sender,\n address operator,\n uint256 id\n ) external;\n\n function batchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n bytes calldata data\n ) external;\n\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n bytes calldata data\n ) external;\n\n function setApprovalForAllFor(\n address sender,\n address operator,\n bool approved\n ) external;\n\n function burn(uint256 id) external;\n\n function burnFrom(address from, uint256 id) external;\n}\n" + }, + "src/solc_0.8/common/interfaces/IERC721ExtendedToken.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\ninterface IERC721ExtendedToken {\n function approveFor(\n address sender,\n address operator,\n uint256 id\n ) external;\n\n function batchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids\n ) external;\n\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n bytes calldata data\n ) external;\n\n function setApprovalForAllFor(\n address sender,\n address operator,\n bool approved\n ) external;\n\n function burn(uint256 id) external;\n\n function burnFrom(address from, uint256 id) external;\n}\n" + }, + "src/solc_0.8/common/interfaces/IERC721MandatoryTokenReceiver.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\n/**\n * @title IERC721MandatoryTokenReceiver\n * @author The Sandbox\n * @notice Interface for any contract that wants to support safeBatchTransfers\n * from ERC721 asset contracts.\n * @dev The ERC-165 identifier for this interface is 0x5e8bf644.\n */\ninterface IERC721MandatoryTokenReceiver {\n /**\n * @notice Whenever tokens are transferred to this contract via {IERC721-safeBatchTransferFrom}\n * by `operator` from `from`, this function is called.\n * @param operator sender\n * @param from owner of the tokens\n * @param ids token ids\n * @param data extra data\n * @return 0x4b808c46 if the transfer is a success\n */\n function onERC721BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n bytes calldata data\n ) external returns (bytes4); // needs to return 0x4b808c46\n\n /**\n * @notice Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n * @param operator sender\n * @param from owner of the token\n * @param tokenId token id\n * @param data extra data\n * @return 0x4b808c46 if the transfer is a success\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4); // needs to return 0x150b7a02\n}\n" + }, + "src/solc_0.8/common/interfaces/IERC721Minter.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\ninterface IERC721Minter {\n function mint(address to, uint256 id) external;\n\n function mint(\n address to,\n uint256 id,\n bytes calldata data\n ) external;\n}\n" + }, + "src/solc_0.8/common/interfaces/IERC721Token.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\ninterface IERC721Token {\n function mint(address to, uint256 id) external;\n\n function mint(\n address to,\n uint256 id,\n bytes calldata metaData\n ) external;\n\n function burnFrom(address from, uint256 id) external;\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n function exists(uint256 tokenId) external view returns (bool);\n}\n" + }, + "src/solc_0.8/common/interfaces/IERC721TokenReceiver.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\n/* This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at http://mozilla.org/MPL/2.0/.\n *\n * This code has not been reviewed.\n * Do not use or deploy this code before reviewing it personally first.\n */\n\ninterface IERC721TokenReceiver {\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "src/solc_0.8/common/interfaces/ILandToken.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\n/// @title ILandToken\n/// @author The Sandbox\n/// @notice Interface of the LAND token including quad methods\ninterface ILandToken {\n /// @notice transfer multiple quad (aligned to a quad tree with size 3, 6, 12 or 24 only)\n /// @param from current owner of the quad\n /// @param to destination\n /// @param sizes list of sizes for each quad\n /// @param xs list of bottom left x coordinates for each quad\n /// @param ys list of bottom left y coordinates for each quad\n /// @param data additional data\n function batchTransferQuad(\n address from,\n address to,\n uint256[] calldata sizes,\n uint256[] calldata xs,\n uint256[] calldata ys,\n bytes calldata data\n ) external;\n\n /// @notice transfer one quad (aligned to a quad tree with size 3, 6, 12 or 24 only)\n /// @param from current owner of the quad\n /// @param to destination\n /// @param size size of the quad\n /// @param x The top left x coordinate of the quad\n /// @param y The top left y coordinate of the quad\n /// @param data additional data\n function transferQuad(\n address from,\n address to,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes calldata data\n ) external;\n\n /// @notice Transfer many tokens between 2 addresses.\n /// @param from The sender of the token.\n /// @param to The recipient of the token.\n /// @param ids The ids of the tokens.\n /// @param data Additional data.\n function batchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n bytes calldata data\n ) external;\n}\n" + }, + "src/solc_0.8/common/interfaces/ILandTokenV2.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"./ILandToken.sol\";\n\n/**\n * @title ILandTokenV2\n * @author The Sandbox\n * @notice Interface of the LAND token including quad methods\n */\ninterface ILandTokenV2 is ILandToken {\n /**\n * @notice Checks if an address if an operator\n * @param who address checked\n * @return is it super operator\n */\n function isSuperOperator(address who) external view returns (bool);\n\n /**\n * @notice Checks if a LAND exists by its coordinates\n * @param size size of the quad\n * @param x x coordinate\n * @param y y coordinate\n * @return does the LAND exist\n */\n function exists(\n uint256 size,\n uint256 x,\n uint256 y\n ) external view returns (bool);\n\n /**\n * @notice Mint a new quad (aligned to a quad tree with size 1, 3, 6, 12 or 24 only)\n * @param to The recipient of the new quad\n * @param size The size of the new quad\n * @param x The top left x coordinate of the new quad\n * @param y The top left y coordinate of the new quad\n * @param data extra data to pass to the transfer\n */\n function mintQuad(\n address to,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes calldata data\n ) external;\n\n /**\n * @notice Checks if a parent quad has child quads already minted.\n * Then mints the rest child quads and transfers the parent quad.\n * Should only be called by the tunnel.\n * @param to The recipient of the new quad\n * @param size The size of the new quad\n * @param x The top left x coordinate of the new quad\n * @param y The top left y coordinate of the new quad\n * @param data extra data to pass to the transfer\n */\n function mintAndTransferQuad(\n address to,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes calldata data\n ) external;\n}\n" + }, + "src/solc_0.8/common/interfaces/ILandTokenV3.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"./ILandTokenV2.sol\";\n\ninterface ILandTokenV3 is ILandTokenV2 {\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n bytes memory data\n ) external;\n\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n bytes calldata data\n ) external;\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id\n ) external;\n}\n" + }, + "src/solc_0.8/common/interfaces/IMintableERC1155.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\ninterface IMintableERC1155 {\n /**\n * @notice Creates `amount` tokens of token type `id`, and assigns them to `account`.\n * @dev Should be callable only by MintableERC1155Predicate\n * Make sure minting is done only by this function\n * @param account user address for whom token is being minted\n * @param id token which is being minted\n * @param amount amount of token being minted\n * @param data extra byte data to be accompanied with minted tokens\n */\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @notice Batched version of singular token minting, where\n * for each token in `ids` respective amount to be minted from `amounts`\n * array, for address `to`.\n * @dev Should be callable only by MintableERC1155Predicate\n * Make sure minting is done only by this function\n * @param to user address for whom token is being minted\n * @param ids tokens which are being minted\n * @param amounts amount of each token being minted\n * @param data extra byte data to be accompanied with minted tokens\n */\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "src/solc_0.8/common/interfaces/IMintableERC721.sol": { + "content": "//SPDX-License-Identifier: MIT\n// import {IERC721} from \"@openzeppelin/contracts-0.8/token/ERC721/IERC721.sol\";\n\npragma solidity 0.8.2;\n\ninterface IMintableERC721 {\n // is IERC721 {\n\n /**\n * @notice called by predicate contract to mint tokens while withdrawing\n * @dev Should be callable only by MintableERC721Predicate\n * Make sure minting is done only by this function\n * @param user user address for whom token is being minted\n * @param tokenId tokenId being minted\n */\n function mint(address user, uint256 tokenId) external;\n\n /**\n * @notice called by predicate contract to mint tokens while withdrawing with metadata from L2\n * @dev Should be callable only by MintableERC721Predicate\n * Make sure minting is only done either by this function/ 👆\n * @param user user address for whom token is being minted\n * @param tokenId tokenId being minted\n * @param metaData Associated token metadata, to be decoded & set using `setTokenMetadata`\n *\n * Note : If you're interested in taking token metadata from L2 to L1 during exit, you must\n * implement this method\n */\n function mint(\n address user,\n uint256 tokenId,\n bytes calldata metaData\n ) external;\n\n /**\n * @notice check if token already exists, return true if it does exist\n * @dev this check will be used by the predicate to determine if the token needs to be minted or transfered\n * @param tokenId tokenId being checked\n */\n function exists(uint256 tokenId) external view returns (bool);\n\n // This one came form ERC721 and is used by the predicate!!!\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n}\n" + }, + "src/solc_0.8/common/interfaces/IPolygonAssetERC1155.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {IAssetERC721} from \"./IAssetERC721.sol\";\n\ninterface IPolygonAssetERC1155 {\n function changeBouncerAdmin(address newBouncerAdmin) external;\n\n function setBouncer(address bouncer, bool enabled) external;\n\n function setPredicate(address predicate) external;\n\n function mint(\n address creator,\n uint40 packId,\n bytes32 hash,\n uint256 supply,\n address owner,\n bytes calldata data\n ) external returns (uint256 id);\n\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n function mintDeficit(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n function mintMultiple(\n address creator,\n uint40 packId,\n bytes32 hash,\n uint256[] calldata supplies,\n bytes calldata rarityPack,\n address owner,\n bytes calldata data\n ) external returns (uint256[] memory ids);\n\n // fails on non-NFT or nft who do not have collection (was a mistake)\n function collectionOf(uint256 id) external view returns (uint256);\n\n function balanceOf(address owner, uint256 id) external view returns (uint256);\n\n // return true for Non-NFT ERC1155 tokens which exists\n function isCollection(uint256 id) external view returns (bool);\n\n function collectionIndexOf(uint256 id) external view returns (uint256);\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external;\n\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external;\n\n function burnFrom(\n address from,\n uint256 id,\n uint256 amount\n ) external;\n\n function getBouncerAdmin() external view returns (address);\n\n function extractERC721From(\n address sender,\n uint256 id,\n address to\n ) external returns (uint256 newId);\n\n function isBouncer(address who) external view returns (bool);\n\n function creatorOf(uint256 id) external view returns (address);\n\n function doesHashExist(uint256 id) external view returns (bool);\n\n function isSuperOperator(address who) external view returns (bool);\n\n function isApprovedForAll(address owner, address operator) external view returns (bool isOperator);\n\n function setApprovalForAllFor(\n address sender,\n address operator,\n bool approved\n ) external;\n\n function setApprovalForAll(address operator, bool approved) external;\n\n function balanceOfBatch(address[] calldata owners, uint256[] calldata ids) external returns (uint256[] memory);\n\n function name() external returns (string memory _name);\n\n function symbol() external returns (string memory _symbol);\n\n function supportsInterface(bytes4 id) external returns (bool);\n\n function uri(uint256 id) external returns (string memory);\n\n function setAssetERC721(IAssetERC721 assetERC721) external;\n\n function exists(uint256 tokenId) external view returns (bool);\n\n function setTrustedForwarder(address trustedForwarder) external;\n\n function isTrustedForwarder(address forwarder) external returns (bool);\n\n function getTrustedForwarder() external returns (address);\n\n function metadataHash(uint256 id) external returns (bytes32);\n}\n" + }, + "src/solc_0.8/common/interfaces/IPolygonAssetERC721.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {IERC721Base} from \"./IERC721Base.sol\";\n\ninterface IPolygonAssetERC721 is IERC721Base {\n function setTokenURI(uint256 id, string memory uri) external;\n\n function tokenURI(uint256 id) external view returns (string memory);\n}\n" + }, + "src/solc_0.8/common/interfaces/IPolygonLand.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {ILandToken} from \"./ILandToken.sol\";\n\n/**\n * @title IPolygonLand\n * @author The Sandbox\n * @notice Interface of the LAND token on the child chain\n */\ninterface IPolygonLand is ILandToken {\n /**\n * @notice Mint a new quad (aligned to a quad tree with size 1, 3, 6, 12 or 24 only)\n * @param to The recipient of the new quad\n * @param size The size of the new quad\n * @param x The top left x coordinate of the new quad\n * @param y The top left y coordinate of the new quad\n * @param data extra data to pass to the transfer\n */\n function mintQuad(\n address to,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes memory data\n ) external;\n\n /**\n * @notice Checks if a LAND exists by its coordinates\n * @param size size of the quad\n * @param x x coordinate\n * @param y y coordinate\n * @return does the LAND exist\n */\n function exists(\n uint256 size,\n uint256 x,\n uint256 y\n ) external view returns (bool);\n}\n" + }, + "src/solc_0.8/common/interfaces/IPolygonLandTunnel.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\n/**\n * @title IPolygonLandTunnel\n * @author The Sandbox\n * @notice Interface of the LAND tunnel on the child chain\n */\ninterface IPolygonLandTunnel {\n /**\n * @notice Withdraw multiple quads to the root chain\n * @param to the recipient\n * @param sizes size of the quads\n * @param xs x of the quads\n * @param ys y of the quads\n * @param data extra data\n */\n function batchTransferQuadToL1(\n address to,\n uint256[] calldata sizes,\n uint256[] calldata xs,\n uint256[] calldata ys,\n bytes memory data\n ) external;\n}\n" + }, + "src/solc_0.8/common/interfaces/IPolygonLandV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"./IPolygonLand.sol\";\n\n/**\n * @title IPolygonLandV2\n * @author The Sandbox\n * @notice interface of the LAND v2 based on IPolygonLand\n */\ninterface IPolygonLandV2 is IPolygonLand {\n /**\n * @notice checks if an address if an operator\n * @param who address checked\n * @return is it super operator\n */\n function isSuperOperator(address who) external view returns (bool);\n\n /**\n * @notice checks if a parent quad has child quads already minted.\n * Then mints the rest child quads and transfers the parent quad.\n * Should only be called by the tunnel.\n * @param to The recipient of the new quad\n * @param size The size of the new quad\n * @param x The top left x coordinate of the new quad\n * @param y The top left y coordinate of the new quad\n * @param data extra data to pass to the transfer\n */\n function mintAndTransferQuad(\n address to,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes calldata data\n ) external;\n}\n" + }, + "src/solc_0.8/common/interfaces/IPolygonLandWithSetApproval.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {IPolygonLand} from \"./IPolygonLand.sol\";\n\n/**\n * @title IPolygonLandWithSetApproval\n * @author The Sandbox\n * @notice Approve for all interface for the LAND on the chain root\n */\ninterface IPolygonLandWithSetApproval is IPolygonLand {\n /**\n * @notice Approve or disapprove the operator for all the tokens\n * @param operator address to approve\n * @param approved should it be approved or not\n */\n function setApprovalForAll(address operator, bool approved) external;\n}\n" + }, + "src/solc_0.8/common/interfaces/Medianizer.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\n/**\n * @title Medianizer contract\n * @dev From MakerDAO (https://etherscan.io/address/0x729D19f657BD0614b4985Cf1D82531c67569197B#code)\n */\ninterface Medianizer {\n function read() external view returns (bytes32);\n}\n" + }, + "src/solc_0.8/common/interfaces/pos-portal/child/IChildToken.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n}\n" + }, + "src/solc_0.8/common/interfaces/pos-portal/root/IRootERC721.sol": { + "content": "//SPDX-License-Identifier: MIT\n// import {IERC721} from \"@openzeppelin/contracts-0.8/token/ERC721/IERC721.sol\";\n\npragma solidity 0.8.2;\n\ninterface IRootERC721 {\n // is IERC721 {\n // Make sure you implement this method in root ERC721\n // contract when you're interested in transferring\n // metadata from L2 to L1\n function setTokenMetadata(uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "src/solc_0.8/common/Libraries/BytesUtil.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nlibrary BytesUtil {\n uint256 private constant DATA_MIN_LENGTH = 68;\n\n /// @dev Check if the data == _address.\n /// @param data The bytes passed to the function.\n /// @param _address The address to compare to.\n /// @return Whether the first param == _address.\n function doFirstParamEqualsAddress(bytes memory data, address _address) internal pure returns (bool) {\n if (data.length < DATA_MIN_LENGTH) {\n return false;\n }\n uint256 value;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n value := mload(add(data, 36))\n }\n return value == uint256(uint160(_address));\n }\n}\n" + }, + "src/solc_0.8/common/Libraries/ObjectLib32.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\nlibrary ObjectLib32 {\n enum Operations {ADD, SUB, REPLACE}\n // Constants regarding bin or chunk sizes for balance packing\n uint256 internal constant TYPES_BITS_SIZE = 32; // Max size of each object\n uint256 internal constant TYPES_PER_UINT256 = 256 / TYPES_BITS_SIZE; // Number of types per uint256\n uint256 internal constant TYPE_ELIMINATOR = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFF;\n\n //\n // Objects and Tokens Functions\n //\n\n /// @dev Return the bin number and index within that bin where ID is\n /// @param tokenId Object type\n /// @return bin Bin number.\n /// @return index ID's index within that bin.\n function getTokenBinIndex(uint256 tokenId) internal pure returns (uint256 bin, uint256 index) {\n uint256 id = tokenId & TYPE_ELIMINATOR;\n unchecked {bin = (id * TYPES_BITS_SIZE) / 256;}\n index = tokenId % TYPES_PER_UINT256;\n return (bin, index);\n }\n\n /**\n * @dev update the balance of a type provided in binBalances\n * @param binBalances Uint256 containing the balances of objects\n * @param index Index of the object in the provided bin\n * @param amount Value to update the type balance\n * @param operation Which operation to conduct :\n * Operations.REPLACE : Replace type balance with amount\n * Operations.ADD : ADD amount to type balance\n * Operations.SUB : Substract amount from type balance\n */\n function updateTokenBalance(\n uint256 binBalances,\n uint256 index,\n uint256 amount,\n Operations operation\n ) internal pure returns (uint256 newBinBalance) {\n uint256 objectBalance = 0;\n if (operation == Operations.ADD) {\n objectBalance = getValueInBin(binBalances, index);\n newBinBalance = writeValueInBin(binBalances, index, objectBalance + amount);\n } else if (operation == Operations.SUB) {\n objectBalance = getValueInBin(binBalances, index);\n require(objectBalance >= amount, \"can't substract more than there is\");\n newBinBalance = writeValueInBin(binBalances, index, objectBalance - amount);\n } else if (operation == Operations.REPLACE) {\n newBinBalance = writeValueInBin(binBalances, index, amount);\n } else {\n revert(\"Invalid operation\"); // Bad operation\n }\n\n return newBinBalance;\n }\n\n /*\n * @dev return value in binValue at position index\n * @param binValue uint256 containing the balances of TYPES_PER_UINT256 types\n * @param index index at which to retrieve value\n * @return Value at given index in bin\n */\n function getValueInBin(uint256 binValue, uint256 index) internal pure returns (uint256) {\n // Mask to retrieve data for a given binData\n uint256 mask = (uint256(1) << TYPES_BITS_SIZE) - 1;\n\n // Shift amount\n uint256 rightShift = 256 - TYPES_BITS_SIZE * (index + 1);\n return (binValue >> rightShift) & mask;\n }\n\n /**\n * @dev return the updated binValue after writing amount at index\n * @param binValue uint256 containing the balances of TYPES_PER_UINT256 types\n * @param index Index at which to retrieve value\n * @param amount Value to store at index in bin\n * @return Value at given index in bin\n */\n function writeValueInBin(\n uint256 binValue,\n uint256 index,\n uint256 amount\n ) internal pure returns (uint256) {\n require(amount < 2**TYPES_BITS_SIZE, \"Amount to write in bin is too large\");\n\n // Mask to retrieve data for a given binData\n uint256 mask = (uint256(1) << TYPES_BITS_SIZE) - 1;\n\n // Shift amount\n uint256 leftShift = 256 - TYPES_BITS_SIZE * (index + 1);\n return (binValue & ~(mask << leftShift)) | (amount << leftShift);\n }\n}\n" + }, + "src/solc_0.8/common/Libraries/PriceUtil.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nlibrary PriceUtil {\n function calculateCurrentPrice(\n uint256 startingPrice,\n uint256 endingPrice,\n uint256 duration,\n uint256 secondsPassed\n ) internal pure returns (uint256) {\n if (secondsPassed > duration) {\n return endingPrice;\n }\n if (endingPrice == startingPrice) {\n return endingPrice;\n } else if (endingPrice > startingPrice) {\n return startingPrice + ((endingPrice - startingPrice) * secondsPassed) / duration;\n } else {\n return startingPrice - ((startingPrice - endingPrice) * secondsPassed) / duration;\n }\n }\n\n function calculateFee(uint256 price, uint256 fee10000th) internal pure returns (uint256) {\n // _fee < 10000, so the result will be <= price\n return (price * fee10000th) / 10000;\n }\n}\n" + }, + "src/solc_0.8/common/Libraries/SafeMathWithRequire.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\n/**\n * @title SafeMath\n * @dev Math operations with safety checks that revert\n */\nlibrary SafeMathWithRequire {\n uint256 private constant DECIMALS_18 = 1000000000000000000;\n uint256 private constant DECIMALS_12 = 1000000000000;\n uint256 private constant DECIMALS_9 = 1000000000;\n uint256 private constant DECIMALS_6 = 1000000;\n\n function sqrt6(uint256 a) internal pure returns (uint256 c) {\n a = a * DECIMALS_12;\n uint256 tmp = (a + 1) / 2;\n c = a;\n // tmp cannot be zero unless a = 0 which skip the loop\n while (tmp < c) {\n c = tmp;\n tmp = ((a / tmp) + tmp) / 2;\n }\n }\n\n function sqrt3(uint256 a) internal pure returns (uint256 c) {\n a = a * DECIMALS_6;\n uint256 tmp = (a + 1) / 2;\n c = a;\n // tmp cannot be zero unless a = 0 which skip the loop\n while (tmp < c) {\n c = tmp;\n tmp = ((a / tmp) + tmp) / 2;\n }\n }\n\n function cbrt6(uint256 a) internal pure returns (uint256 c) {\n a = a * DECIMALS_18;\n uint256 tmp = (a + 2) / 3;\n c = a;\n // tmp cannot be zero unless a = 0 which skip the loop\n while (tmp < c) {\n c = tmp;\n uint256 tmpSquare = tmp**2;\n require(tmpSquare > tmp, \"overflow\");\n tmp = ((a / tmpSquare) + (tmp * 2)) / 3;\n }\n return c;\n }\n\n function cbrt3(uint256 a) internal pure returns (uint256 c) {\n a = a * DECIMALS_9;\n uint256 tmp = (a + 2) / 3;\n c = a;\n // tmp cannot be zero unless a = 0 which skip the loop\n while (tmp < c) {\n c = tmp;\n uint256 tmpSquare = tmp**2;\n require(tmpSquare > tmp, \"overflow\");\n tmp = ((a / tmpSquare) + (tmp * 2)) / 3;\n }\n return c;\n }\n}\n" + }, + "src/solc_0.8/common/Libraries/SigUtil.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nlibrary SigUtil {\n function recover(bytes32 hash, bytes memory sig) internal pure returns (address recovered) {\n require(sig.length == 65, \"incorrect signature length\");\n\n bytes32 r;\n bytes32 s;\n uint8 v;\n assembly {\n r := mload(add(sig, 32))\n s := mload(add(sig, 64))\n v := byte(0, mload(add(sig, 96)))\n }\n\n // Version of signature should be 27 or 28, but 0 and 1 are also possible versions\n if (v < 27) {\n v += 27;\n }\n require(v == 27 || v == 28, \"version of signature should be 27 or 28\");\n\n recovered = ecrecover(hash, v, r, s);\n require(recovered != address(0), \"incorrect address\");\n }\n\n function recoverWithZeroOnFailure(bytes32 hash, bytes memory sig) internal pure returns (address) {\n if (sig.length != 65) {\n return (address(0));\n }\n\n bytes32 r;\n bytes32 s;\n uint8 v;\n assembly {\n r := mload(add(sig, 32))\n s := mload(add(sig, 64))\n v := byte(0, mload(add(sig, 96)))\n }\n\n // Version of signature should be 27 or 28, but 0 and 1 are also possible versions\n if (v < 27) {\n v += 27;\n }\n\n if (v != 27 && v != 28) {\n return (address(0));\n } else {\n return ecrecover(hash, v, r, s);\n }\n }\n\n // Builds a prefixed hash to mimic the behavior of eth_sign.\n function prefixed(bytes32 hash) internal pure returns (bytes memory) {\n return abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash);\n }\n}\n" + }, + "src/solc_0.8/defi/contributionCalculation/LandContributionCalculator.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport {Ownable} from \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\nimport {Address} from \"@openzeppelin/contracts-0.8/utils/Address.sol\";\nimport {IERC721} from \"@openzeppelin/contracts-0.8/token/ERC721/IERC721.sol\";\nimport {SafeMathWithRequire} from \"../../common/Libraries/SafeMathWithRequire.sol\";\nimport {IContributionCalculator} from \"../interfaces/IContributionCalculator.sol\";\n\ncontract LandContributionCalculator is IContributionCalculator, Ownable {\n using Address for address;\n\n uint256 internal constant DECIMALS_9 = 1000000000;\n uint256 internal constant MIDPOINT_9 = 500000000;\n uint256 internal constant NFT_FACTOR_6 = 10000;\n uint256 internal constant NFT_CONSTANT_3 = 9000;\n uint256 internal constant ROOT3_FACTOR = 697;\n\n IERC721 public multiplierNFToken;\n\n constructor(IERC721 multiplierNFToken_) {\n multiplierNFToken = multiplierNFToken_;\n }\n\n function multiplierOf(address account) external view virtual returns (uint256) {\n return multiplierNFToken.balanceOf(account);\n }\n\n function computeContribution(address account, uint256 amountStaked) external view override returns (uint256) {\n uint256 numLands = multiplierNFToken.balanceOf(account);\n return _contribution(amountStaked, numLands);\n }\n\n function contribution(uint256 amountStaked, uint256 numLands) external pure returns (uint256) {\n return _contribution(amountStaked, numLands);\n }\n\n function setNFTMultiplierToken(address newNFTMultiplierToken) external onlyOwner {\n require(newNFTMultiplierToken.isContract(), \"LandContributionCalc: Bad NFTMultiplierToken address\");\n multiplierNFToken = IERC721(newNFTMultiplierToken);\n }\n\n function _contribution(uint256 amountStaked, uint256 numLands) internal pure returns (uint256) {\n if (numLands == 0) {\n return amountStaked;\n }\n uint256 nftContrib =\n NFT_FACTOR_6 * (NFT_CONSTANT_3 + SafeMathWithRequire.cbrt3((((numLands - 1) * ROOT3_FACTOR) + 1)));\n if (nftContrib > MIDPOINT_9) {\n nftContrib = MIDPOINT_9 + (nftContrib - MIDPOINT_9) / 10;\n }\n return amountStaked + ((amountStaked * nftContrib) / DECIMALS_9);\n }\n}\n" + }, + "src/solc_0.8/defi/contributionCalculation/LandOwnerContributionCalculator.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport {Ownable} from \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\nimport {Address} from \"@openzeppelin/contracts-0.8/utils/Address.sol\";\nimport {IERC721} from \"@openzeppelin/contracts-0.8/token/ERC721/IERC721.sol\";\nimport {SafeMathWithRequire} from \"../../common/Libraries/SafeMathWithRequire.sol\";\nimport {IContributionCalculator} from \"../interfaces/IContributionCalculator.sol\";\n\ncontract LandOwnersAloneContributionCalculator is IContributionCalculator, Ownable {\n using Address for address;\n\n IERC721 public multiplierNFToken;\n\n constructor(IERC721 multiplierNFToken_) {\n multiplierNFToken = multiplierNFToken_;\n }\n\n function multiplierOf(address account) external view virtual returns (uint256) {\n return multiplierNFToken.balanceOf(account);\n }\n\n function computeContribution(address account, uint256 amountStaked) external view override returns (uint256) {\n uint256 numLands = multiplierNFToken.balanceOf(account);\n if (numLands > 0) {\n return amountStaked;\n }\n return 0;\n }\n\n function setNFTMultiplierToken(address newNFTMultiplierToken) external onlyOwner {\n require(newNFTMultiplierToken.isContract(), \"LandOwnersAloneContributionCalc: Bad NFTMultiplierToken address\");\n multiplierNFToken = IERC721(newNFTMultiplierToken);\n }\n}\n" + }, + "src/solc_0.8/defi/ERC20RewardPool.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport {Context} from \"@openzeppelin/contracts-0.8/utils/Context.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts-0.8/token/ERC20/utils/SafeERC20.sol\";\nimport {IERC20} from \"@openzeppelin/contracts-0.8/token/ERC20/IERC20.sol\";\nimport {ReentrancyGuard} from \"@openzeppelin/contracts-0.8/security/ReentrancyGuard.sol\";\nimport {Address} from \"@openzeppelin/contracts-0.8/utils/Address.sol\";\nimport {Pausable} from \"@openzeppelin/contracts-0.8/security/Pausable.sol\";\nimport {Ownable} from \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\nimport {Math} from \"@openzeppelin/contracts-0.8/utils/math/Math.sol\";\nimport {ERC2771HandlerV2} from \"../common/BaseWithStorage/ERC2771HandlerV2.sol\";\nimport {StakeTokenWrapper} from \"./StakeTokenWrapper.sol\";\nimport {IContributionRules} from \"./interfaces/IContributionRules.sol\";\nimport {IRewardCalculator} from \"./interfaces/IRewardCalculator.sol\";\nimport {LockRules} from \"./rules/LockRules.sol\";\nimport {RequirementsRules} from \"./rules/RequirementsRules.sol\";\n\n/// @title A pool that distributes rewards between users that stake any erc20 token\n/// @notice The contributions are updated passively, an external call to computeContribution from a backend is needed.\n/// @notice After initialization the reward calculator must be set by the admin.\n/// @dev The contract has two plugins that affect the behaviour: contributionCalculator and rewardCalculator\n/// @dev contributionCalculator instead of using the stake directly the result of computeContribution is used\n/// @dev this way some users can get an extra share of the rewards\n/// @dev rewardCalculator is used to manage the rate at which the rewards are distributed.\n/// @dev This way we can build different types of pools by mixing in the plugins we want with this contract.\n/// @dev default behaviour (address(0)) for contributionCalculator is to use the stacked amount as contribution.\n/// @dev default behaviour (address(0)) for rewardCalculator is that no rewards are given\ncontract ERC20RewardPool is\n Ownable,\n StakeTokenWrapper,\n LockRules,\n RequirementsRules,\n ReentrancyGuard,\n ERC2771HandlerV2,\n Pausable\n{\n using SafeERC20 for IERC20;\n using Address for address;\n\n event Staked(address indexed account, uint256 stakeAmount);\n event Withdrawn(address indexed account, uint256 stakeAmount);\n event Exit(address indexed account);\n event RewardPaid(address indexed account, uint256 rewardAmount);\n event ContributionUpdated(address indexed account, uint256 newContribution, uint256 oldContribution);\n\n uint256 internal constant DECIMALS_18 = 1 ether;\n\n // This value multiplied by the user contribution is the share of accumulated rewards (from the start of time\n // until the last call to restartRewards) for the user taking into account the value of totalContributions.\n uint256 public rewardPerTokenStored;\n\n IERC20 public rewardToken;\n IContributionRules public contributionRules;\n IRewardCalculator public rewardCalculator;\n\n // This value multiplied by the user contribution is the share of reward from the the last time\n // the user changed his contribution and called restartRewards\n mapping(address => uint256) public userRewardPerTokenPaid;\n\n // This value is the accumulated rewards won by the user when he called the contract.\n mapping(address => uint256) public rewards;\n\n uint256 internal _totalContributions;\n mapping(address => uint256) internal _contributions;\n\n constructor(\n IERC20 stakeToken_,\n IERC20 rewardToken_,\n address trustedForwarder\n ) StakeTokenWrapper(stakeToken_) {\n require(address(rewardToken_).isContract(), \"ERC20RewardPool: is not a contract\");\n rewardToken = rewardToken_;\n __ERC2771HandlerV2_initialize(trustedForwarder);\n }\n\n // Checks that the given address is a contract and\n // that the caller of the method is the owner of this contract - ERC20RewardPool.\n modifier isContractAndAdmin(address contractAddress) {\n require(contractAddress.isContract(), \"ERC20RewardPool: is not a contract\");\n require(owner() == _msgSender(), \"ERC20RewardPool: not admin\");\n _;\n }\n\n modifier isValidAddress(address account) {\n require(account != address(0), \"ERC20RewardPool: zero address\");\n\n _;\n }\n\n /// @notice set the reward token\n /// @param contractAddress address token used to pay rewards\n function setRewardToken(address contractAddress)\n external\n isContractAndAdmin(contractAddress)\n isValidAddress(contractAddress)\n {\n IERC20 _newRewardToken = IERC20(contractAddress);\n require(\n rewardToken.balanceOf(address(this)) <= _newRewardToken.balanceOf(address(this)),\n \"ERC20RewardPool: insufficient balance\"\n );\n rewardToken = _newRewardToken;\n }\n\n /// @notice set the stake token\n /// @param contractAddress address token used to stake funds\n function setStakeToken(address contractAddress)\n external\n isContractAndAdmin(contractAddress)\n isValidAddress(contractAddress)\n {\n IERC20 _newStakeToken = IERC20(contractAddress);\n require(\n _stakeToken.balanceOf(address(this)) <= _newStakeToken.balanceOf(address(this)),\n \"ERC20RewardPool: insufficient balance\"\n );\n _stakeToken = _newStakeToken;\n }\n\n /// @notice set the trusted forwarder\n /// @param trustedForwarder address of the contract that is enabled to send meta-tx on behalf of the user\n function setTrustedForwarder(address trustedForwarder) external isContractAndAdmin(trustedForwarder) {\n _trustedForwarder = trustedForwarder;\n }\n\n /// @notice set contract that contains all the contribution rules\n function setContributionRules(address contractAddress)\n external\n isContractAndAdmin(contractAddress)\n isValidAddress(contractAddress)\n {\n contributionRules = IContributionRules(contractAddress);\n }\n\n /// @notice set the reward calculator\n /// @param contractAddress address of a plugin that calculates absolute rewards at any point in time\n /// @param restartRewards_ if true the rewards from the previous calculator are accumulated before changing it\n function setRewardCalculator(address contractAddress, bool restartRewards_)\n external\n isContractAndAdmin(contractAddress)\n isValidAddress(contractAddress)\n {\n // We process the rewards of the current reward calculator before the switch.\n if (restartRewards_) {\n _restartRewards();\n }\n rewardCalculator = IRewardCalculator(contractAddress);\n }\n\n /// @notice the admin recover is able to recover reward funds\n /// @param receiver address of the beneficiary of the recovered funds\n /// @dev this function must be called in an emergency situation only.\n /// @dev Calling it is risky specially when rewardToken == stakeToken\n function recoverFunds(address receiver) external onlyOwner whenPaused() isValidAddress(receiver) {\n uint256 recoverAmount;\n\n if (rewardToken == _stakeToken) {\n recoverAmount = rewardToken.balanceOf(address(this)) - _totalSupply;\n } else {\n recoverAmount = rewardToken.balanceOf(address(this));\n }\n\n rewardToken.safeTransfer(receiver, recoverAmount);\n }\n\n /// @notice return the total supply of staked tokens\n /// @return the total supply of staked tokens\n function totalSupply() external view returns (uint256) {\n return _totalSupply;\n }\n\n /// @notice return the balance of staked tokens for a user\n /// @param account the address of the account\n /// @return balance of staked tokens\n function balanceOf(address account) external view returns (uint256) {\n return _balances[account];\n }\n\n /// @notice return the address of the stake token contract\n /// @return address of the stake token contract\n function stakeToken() external view returns (IERC20) {\n return _stakeToken;\n }\n\n /// @notice return the amount of rewards deposited in the contract that can be distributed by different campaigns\n /// @return the total amount of deposited rewards\n /// @dev this function can be called by a reward calculator to throw if a campaign doesn't have\n /// @dev enough rewards to start\n function getRewardsAvailable() external view returns (uint256) {\n if (address(rewardToken) != address(_stakeToken)) {\n return rewardToken.balanceOf(address(this));\n }\n return _stakeToken.balanceOf(address(this)) - _totalSupply;\n }\n\n /// @notice return the sum of the values returned by the contribution calculator\n /// @return total contributions of the users\n /// @dev this is the same than the totalSupply only if the contribution calculator\n /// @dev uses the staked amount as the contribution of the user which is the default behaviour\n function totalContributions() external view returns (uint256) {\n return _totalContributions;\n }\n\n /// @notice return the contribution of some user\n /// @param account the address of the account\n /// @return contribution of the users\n /// @dev this is the same than the balanceOf only if the contribution calculator\n /// @dev uses the staked amount as the contribution of the user which is the default behaviour\n function contributionOf(address account) external view returns (uint256) {\n return _contributions[account];\n }\n\n /// @notice accumulated rewards taking into account the totalContribution (see: rewardPerTokenStored)\n /// @return the accumulated total rewards\n /// @dev This value multiplied by the user contribution is the share of accumulated rewards for the user. Taking\n /// @dev into account the value of totalContributions.\n function rewardPerToken() external view returns (uint256) {\n return rewardPerTokenStored + _rewardPerToken();\n }\n\n /// @notice available earnings for some user\n /// @param account the address of the account\n /// @return the available earnings for the user\n function earned(address account) external view returns (uint256) {\n return rewards[account] + _earned(account, _rewardPerToken());\n }\n\n /// @notice accumulates the current rewards into rewardPerTokenStored and restart the reward calculator\n /// @dev calling this function makes no difference. It is useful for testing and when the reward calculator\n /// @dev is changed.\n function restartRewards() external {\n _restartRewards();\n }\n\n /// @notice update the contribution for a user\n /// @param account the address of the account\n /// @dev if the user change his holdings (or any other parameter that affect the contribution calculation),\n /// @dev he can the reward distribution to his favor. This function must be called by an external agent ASAP to\n /// @dev update the contribution for the user. We understand the risk but the rewards are distributed slowly so\n /// @dev the user cannot affect the reward distribution heavily.\n function computeContribution(address account) external isValidAddress(account) {\n // We decide to give the user the accumulated rewards even if he cheated a little bit.\n _processRewards(account);\n _updateContribution(account);\n }\n\n /// @notice update the contribution for a sef of users\n /// @param accounts the addresses of the accounts to update\n /// @dev see: computeContribution\n function computeContributionInBatch(address[] calldata accounts) external {\n _restartRewards();\n for (uint256 i = 0; i < accounts.length; i++) {\n address account = accounts[i];\n if (account == address(0)) {\n continue;\n }\n _processAccountRewards(account);\n _updateContribution(account);\n }\n }\n\n /// @notice stake some amount into the contract\n /// @param amount the amount of tokens to stake\n /// @dev the user must approve in the stake token before calling this function\n function stake(uint256 amount)\n external\n nonReentrant\n whenNotPaused()\n antiDepositCheck(_msgSender())\n checkRequirements(_msgSender(), amount, _balances[_msgSender()])\n {\n require(amount > 0, \"ERC20RewardPool: Cannot stake 0\");\n\n // The first time a user stakes he cannot remove his rewards immediately.\n if (timeLockClaim.lastClaim[_msgSender()] == 0) {\n timeLockClaim.lastClaim[_msgSender()] = block.timestamp;\n }\n\n lockDeposit.lastDeposit[_msgSender()] = block.timestamp;\n\n uint256 earlierRewards = 0;\n\n if (_totalContributions == 0 && rewardCalculator != IRewardCalculator(address(0))) {\n earlierRewards = rewardCalculator.getRewards();\n }\n\n _processRewards(_msgSender());\n super._stake(amount);\n _updateContribution(_msgSender());\n require(_contributions[_msgSender()] > 0, \"ERC20RewardPool: not enough contributions\");\n\n if (earlierRewards != 0) {\n rewards[_msgSender()] = rewards[_msgSender()] + earlierRewards;\n }\n emit Staked(_msgSender(), amount);\n }\n\n /// @notice withdraw the stake from the contract\n /// @param amount the amount of tokens to withdraw\n /// @dev the user can withdraw his stake independently from the rewards\n function withdraw(uint256 amount) external nonReentrant whenNotPaused() {\n _processRewards(_msgSender());\n _withdrawStake(_msgSender(), amount);\n _updateContribution(_msgSender());\n }\n\n /// @notice withdraw the stake and the rewards from the contract\n function exit() external nonReentrant whenNotPaused() {\n _processRewards(_msgSender());\n _withdrawStake(_msgSender(), _balances[_msgSender()]);\n _withdrawRewards(_msgSender());\n _updateContribution(_msgSender());\n emit Exit(_msgSender());\n }\n\n /// @notice withdraw the rewards from the contract\n /// @dev the user can withdraw his stake independently from the rewards\n function getReward() external nonReentrant whenNotPaused() {\n _processRewards(_msgSender());\n _withdrawRewards(_msgSender());\n _updateContribution(_msgSender());\n }\n\n function renounceOwnership() public view override onlyOwner {\n revert(\"ERC20RewardPool: can't renounceOwnership\");\n }\n\n function _withdrawStake(address account, uint256 amount) internal antiWithdrawCheck(_msgSender()) {\n require(amount > 0, \"ERC20RewardPool: Cannot withdraw 0\");\n lockWithdraw.lastWithdraw[_msgSender()] = block.timestamp;\n super._withdraw(amount);\n emit Withdrawn(account, amount);\n }\n\n function _withdrawRewards(address account) internal timeLockClaimCheck(account) {\n uint256 reward = rewards[account];\n uint256 mod = 0;\n if (reward > 0) {\n if (amountLockClaim.claimLockEnabled == true) {\n // constrain the reward amount to the integer allowed\n mod = reward % DECIMALS_18;\n reward = reward - mod;\n require(\n amountLockClaim.amount <= reward,\n \"ERC20RewardPool: Cannot withdraw - lockClaim.amount < reward\"\n );\n }\n rewards[account] = mod;\n rewardToken.safeTransfer(account, reward);\n emit RewardPaid(account, reward);\n }\n }\n\n function _updateContribution(address account) internal {\n uint256 oldContribution = _contributions[account];\n _totalContributions = _totalContributions - oldContribution;\n uint256 contribution = _computeContribution(account);\n _totalContributions = _totalContributions + contribution;\n _contributions[account] = contribution;\n emit ContributionUpdated(account, contribution, oldContribution);\n }\n\n function _computeContribution(address account) internal returns (uint256) {\n if (contributionRules == IContributionRules(address(0))) {\n return Math.min(_balances[account], maxStakeAllowedCalculator(account));\n } else {\n return\n contributionRules.computeMultiplier(\n account,\n Math.min(_balances[account], maxStakeAllowedCalculator(account))\n );\n }\n }\n\n // Something changed (stake, withdraw, etc), we distribute current accumulated rewards and start from zero.\n // Called each time there is a change in contract state (stake, withdraw, etc).\n function _processRewards(address account) internal {\n _restartRewards();\n _processAccountRewards(account);\n }\n\n // Update the earnings for this specific user with what he earned until now\n function _processAccountRewards(address account) internal {\n // usually _earned takes _rewardPerToken() but in this method is zero because _restartRewards must be\n // called before _processAccountRewards\n rewards[account] = rewards[account] + _earned(account, 0);\n // restart rewards for this specific user, now earned(account) = 0\n userRewardPerTokenPaid[account] = rewardPerTokenStored;\n }\n\n function _restartRewards() internal {\n if (rewardCalculator != IRewardCalculator(address(0))) {\n // Distribute the accumulated rewards\n rewardPerTokenStored = rewardPerTokenStored + _rewardPerToken();\n // restart rewards so now the rewardCalculator return zero rewards\n rewardCalculator.restartRewards();\n }\n }\n\n function _earned(address account, uint256 rewardPerToken_) internal view returns (uint256) {\n // - userRewardPerTokenPaid[account] * _contributions[account] / _totalContributions is the portion of\n // rewards the last time the user changed his contribution and called _restartRewards\n // (_totalContributions corresponds to previous value of that moment).\n // - rewardPerTokenStored * _contributions[account] is the share of the user from the\n // accumulated rewards (from the start of time until the last call to _restartRewards) with the\n // current value of _totalContributions\n // - _rewardPerToken() * _contributions[account] / _totalContributions is the share of the user of the\n // rewards from the last time anybody called _restartRewards until this moment\n //\n // The important thing to note is that at any moment in time _contributions[account] / _totalContributions is\n // the share of the user even if _totalContributions changes because of other users activity.\n return\n ((rewardPerToken_ + rewardPerTokenStored - userRewardPerTokenPaid[account]) * _contributions[account]) /\n 1e24;\n }\n\n // This function gives the proportion of the total contribution that corresponds to each user from\n // last restartRewards call.\n // _rewardsPerToken() * _contributions[account] is the amount of extra rewards gained from last restartRewards.\n function _rewardPerToken() internal view returns (uint256) {\n if (rewardCalculator == IRewardCalculator(address(0)) || _totalContributions == 0) {\n return 0;\n }\n return (rewardCalculator.getRewards() * 1e24) / _totalContributions;\n }\n\n // @dev Triggers stopped state.\n // The contract must not be paused.\n function pause() external onlyOwner {\n _pause();\n }\n\n // @dev Returns to normal state.\n // The contract must be paused.\n function unpause() external onlyOwner {\n _unpause();\n }\n\n function _msgSender() internal view override(Context, ERC2771HandlerV2) returns (address sender) {\n return ERC2771HandlerV2._msgSender();\n }\n\n function _msgData() internal view override(Context, ERC2771HandlerV2) returns (bytes calldata) {\n return ERC2771HandlerV2._msgData();\n }\n}\n" + }, + "src/solc_0.8/defi/ERC20RewardPoolV2.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport {Context} from \"@openzeppelin/contracts-0.8/utils/Context.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts-0.8/token/ERC20/utils/SafeERC20.sol\";\nimport {IERC20} from \"@openzeppelin/contracts-0.8/token/ERC20/IERC20.sol\";\nimport {ReentrancyGuard} from \"@openzeppelin/contracts-0.8/security/ReentrancyGuard.sol\";\nimport {Address} from \"@openzeppelin/contracts-0.8/utils/Address.sol\";\nimport {Pausable} from \"@openzeppelin/contracts-0.8/security/Pausable.sol\";\nimport {Ownable} from \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\nimport {Math} from \"@openzeppelin/contracts-0.8/utils/math/Math.sol\";\nimport {ERC2771HandlerV3} from \"../common/BaseWithStorage/ERC2771HandlerV3.sol\";\nimport {StakeTokenWrapperV2} from \"./StakeTokenWrapperV2.sol\";\nimport {IContributionRules} from \"./interfaces/IContributionRules.sol\";\nimport {IRewardCalculator} from \"./interfaces/IRewardCalculator.sol\";\nimport {LockRulesV2} from \"./rules-v2/LockRulesV2.sol\";\nimport {RequirementsRulesV2} from \"./rules-v2/RequirementsRulesV2.sol\";\n\n/// @title A pool that distributes rewards between users that stake any erc20 token\n/// @notice The contributions are updated passively, an external call to computeContribution from a backend is needed.\n/// @notice After initialization the reward calculator must be set by the admin.\n/// @dev The contract has two plugins that affect the behaviour: contributionCalculator and rewardCalculator\n/// @dev contributionCalculator instead of using the stake directly the result of computeContribution is used\n/// @dev this way some users can get an extra share of the rewards\n/// @dev rewardCalculator is used to manage the rate at which the rewards are distributed.\n/// @dev This way we can build different types of pools by mixing in the plugins we want with this contract.\n/// @dev default behaviour (address(0)) for contributionCalculator is to use the stacked amount as contribution.\n/// @dev default behaviour (address(0)) for rewardCalculator is that no rewards are given\ncontract ERC20RewardPoolV2 is\n Ownable,\n StakeTokenWrapperV2,\n LockRulesV2,\n RequirementsRulesV2,\n ReentrancyGuard,\n ERC2771HandlerV3,\n Pausable\n{\n using SafeERC20 for IERC20;\n using Address for address;\n\n event RewardTokenSet(address indexed contractAddress);\n event StakeTokenSet(address indexed contractAddress);\n event TrustedForwarderSet(address indexed trustedForwarder);\n event ContributionRulesSet(address indexed contractAddress);\n event RewardCalculatorSet(address indexed contractAddress, bool restartRewards_);\n event FundsRecovered(address indexed receiver, uint256 recoverAmount);\n event Staked(address indexed account, uint256 stakeAmount);\n event Withdrawn(address indexed account, uint256 stakeAmount);\n event Exit(address indexed account);\n event RewardPaid(address indexed account, uint256 rewardAmount);\n event ContributionUpdated(address indexed account, uint256 newContribution, uint256 oldContribution);\n\n uint256 private constant DECIMALS_18 = 1 ether;\n\n // This value multiplied by the user contribution is the share of accumulated rewards (from the start of time\n // until the last call to restartRewards) for the user taking into account the value of totalContributions.\n uint256 public rewardPerTokenStored;\n\n IERC20 public rewardToken;\n IContributionRules public contributionRules;\n IRewardCalculator public rewardCalculator;\n\n // This value multiplied by the user contribution is the share of reward from the the last time\n // the user changed his contribution and called restartRewards\n mapping(address => uint256) public userRewardPerTokenPaid;\n\n // This value is the accumulated rewards won by the user when he called the contract.\n mapping(address => uint256) public rewards;\n\n uint256 internal _totalContributions;\n mapping(address => uint256) internal _contributions;\n\n constructor(\n IERC20 stakeToken_,\n IERC20 rewardToken_,\n address trustedForwarder\n ) StakeTokenWrapperV2(stakeToken_) {\n require(address(rewardToken_).isContract(), \"ERC20RewardPool: is not a contract\");\n rewardToken = rewardToken_;\n __ERC2771HandlerV3_initialize(trustedForwarder);\n }\n\n modifier isValidAddress(address account) {\n require(account != address(0), \"ERC20RewardPool: zero address\");\n\n _;\n }\n\n /// @notice set the reward token\n /// @param contractAddress address token used to pay rewards\n function setRewardToken(address contractAddress)\n external\n isContract(contractAddress)\n isValidAddress(contractAddress)\n onlyOwner\n {\n IERC20 _newRewardToken = IERC20(contractAddress);\n require(\n rewardToken.balanceOf(address(this)) <= _newRewardToken.balanceOf(address(this)),\n \"ERC20RewardPool: insufficient balance\"\n );\n rewardToken = _newRewardToken;\n\n emit RewardTokenSet(contractAddress);\n }\n\n /// @notice set the stake token\n /// @param contractAddress address token used to stake funds\n function setStakeToken(address contractAddress)\n external\n isContract(contractAddress)\n isValidAddress(contractAddress)\n onlyOwner\n {\n IERC20 _newStakeToken = IERC20(contractAddress);\n require(\n _stakeToken.balanceOf(address(this)) <= _newStakeToken.balanceOf(address(this)),\n \"ERC20RewardPool: insufficient balance\"\n );\n _stakeToken = _newStakeToken;\n\n emit StakeTokenSet(contractAddress);\n }\n\n /// @notice set the trusted forwarder\n /// @param trustedForwarder address of the contract that is enabled to send meta-tx on behalf of the user\n function setTrustedForwarder(address trustedForwarder) external isContract(trustedForwarder) onlyOwner {\n _trustedForwarder = trustedForwarder;\n\n emit TrustedForwarderSet(trustedForwarder);\n }\n\n /// @notice set contract that contains all the contribution rules\n function setContributionRules(address contractAddress)\n external\n isContract(contractAddress)\n isValidAddress(contractAddress)\n onlyOwner\n {\n contributionRules = IContributionRules(contractAddress);\n\n emit ContributionRulesSet(contractAddress);\n }\n\n /// @notice set the reward calculator\n /// @param contractAddress address of a plugin that calculates absolute rewards at any point in time\n /// @param restartRewards_ if true the rewards from the previous calculator are accumulated before changing it\n function setRewardCalculator(address contractAddress, bool restartRewards_)\n external\n isContract(contractAddress)\n isValidAddress(contractAddress)\n onlyOwner\n {\n // We process the rewards of the current reward calculator before the switch.\n if (restartRewards_) {\n _restartRewards();\n }\n rewardCalculator = IRewardCalculator(contractAddress);\n\n emit RewardCalculatorSet(contractAddress, restartRewards_);\n }\n\n /// @notice the admin recover is able to recover reward funds\n /// @param receiver address of the beneficiary of the recovered funds\n /// @dev this function must be called in an emergency situation only.\n /// @dev Calling it is risky specially when rewardToken == stakeToken\n function recoverFunds(address receiver) external onlyOwner whenPaused() isValidAddress(receiver) {\n uint256 recoverAmount;\n\n if (rewardToken == _stakeToken) {\n recoverAmount = rewardToken.balanceOf(address(this)) - _totalSupply;\n } else {\n recoverAmount = rewardToken.balanceOf(address(this));\n }\n\n rewardToken.safeTransfer(receiver, recoverAmount);\n\n emit FundsRecovered(receiver, recoverAmount);\n }\n\n /// @notice return the total supply of staked tokens\n /// @return the total supply of staked tokens\n function totalSupply() external view returns (uint256) {\n return _totalSupply;\n }\n\n /// @notice return the balance of staked tokens for a user\n /// @param account the address of the account\n /// @return balance of staked tokens\n function balanceOf(address account) external view returns (uint256) {\n return _balances[account];\n }\n\n /// @notice return the address of the stake token contract\n /// @return address of the stake token contract\n function stakeToken() external view returns (IERC20) {\n return _stakeToken;\n }\n\n /// @notice return the amount of rewards deposited in the contract that can be distributed by different campaigns\n /// @return the total amount of deposited rewards\n /// @dev this function can be called by a reward calculator to throw if a campaign doesn't have\n /// @dev enough rewards to start\n function getRewardsAvailable() public view returns (uint256) {\n if (address(rewardToken) != address(_stakeToken)) {\n return rewardToken.balanceOf(address(this));\n }\n return rewardToken.balanceOf(address(this)) - _totalSupply;\n }\n\n /// @notice return the sum of the values returned by the contribution calculator\n /// @return total contributions of the users\n /// @dev this is the same than the totalSupply only if the contribution calculator\n /// @dev uses the staked amount as the contribution of the user which is the default behaviour\n function totalContributions() external view returns (uint256) {\n return _totalContributions;\n }\n\n /// @notice return the contribution of some user\n /// @param account the address of the account\n /// @return contribution of the users\n /// @dev this is the same than the balanceOf only if the contribution calculator\n /// @dev uses the staked amount as the contribution of the user which is the default behaviour\n function contributionOf(address account) external view returns (uint256) {\n return _contributions[account];\n }\n\n /// @notice accumulated rewards taking into account the totalContribution (see: rewardPerTokenStored)\n /// @return the accumulated total rewards\n /// @dev This value multiplied by the user contribution is the share of accumulated rewards for the user. Taking\n /// @dev into account the value of totalContributions.\n function rewardPerToken() external view returns (uint256) {\n return rewardPerTokenStored + _rewardPerToken();\n }\n\n /// @notice available earnings for some user\n /// @param account the address of the account\n /// @return the available earnings for the user\n function earned(address account) external view returns (uint256) {\n return rewards[account] + _earned(account, _rewardPerToken());\n }\n\n /// @notice accumulates the current rewards into rewardPerTokenStored and restart the reward calculator\n /// @dev calling this function makes no difference. It is useful for testing and when the reward calculator\n /// @dev is changed.\n function restartRewards() external {\n _restartRewards();\n }\n\n /// @notice update the contribution for a user\n /// @param account the address of the account\n /// @dev if the user change his holdings (or any other parameter that affect the contribution calculation),\n /// @dev he can the reward distribution to his favor. This function must be called by an external agent ASAP to\n /// @dev update the contribution for the user. We understand the risk but the rewards are distributed slowly so\n /// @dev the user cannot affect the reward distribution heavily.\n function computeContribution(address account) external isValidAddress(account) {\n // We decide to give the user the accumulated rewards even if he cheated a little bit.\n _processRewards(account);\n _updateContribution(account);\n }\n\n /// @notice update the contribution for a sef of users\n /// @param accounts the addresses of the accounts to update\n /// @dev see: computeContribution\n function computeContributionInBatch(address[] calldata accounts) external {\n _restartRewards();\n for (uint256 i; i < accounts.length; ) {\n address account = accounts[i];\n if (account == address(0)) {\n continue;\n }\n _processAccountRewards(account);\n _updateContribution(account);\n\n unchecked {i++;}\n }\n }\n\n /// @notice stake some amount into the contract\n /// @param amount the amount of tokens to stake\n /// @dev the user must approve in the stake token before calling this function\n function stake(uint256 amount)\n external\n nonReentrant\n whenNotPaused()\n antiDepositCheck(_msgSender())\n checkRequirements(_msgSender(), amount, _balances[_msgSender()])\n {\n require(amount > 0, \"ERC20RewardPool: Cannot stake 0\");\n\n address _sender = _msgSender();\n\n // The first time a user stakes he cannot remove his rewards immediately.\n if (timeLockClaim.lastClaim[_sender] == 0) {\n timeLockClaim.lastClaim[_sender] = block.timestamp;\n }\n\n uint256 earlierRewards;\n\n if (_totalContributions == 0 && rewardCalculator != IRewardCalculator(address(0))) {\n earlierRewards = rewardCalculator.getRewards();\n }\n\n _processRewards(_sender);\n super._stake(amount);\n _updateContribution(_sender);\n require(_contributions[_sender] > 0, \"ERC20RewardPool: not enough contributions\");\n\n if (earlierRewards != 0) {\n rewards[_sender] = rewards[_sender] + earlierRewards;\n }\n emit Staked(_sender, amount);\n }\n\n /// @notice withdraw the stake from the contract\n /// @param amount the amount of tokens to withdraw\n /// @dev the user can withdraw his stake independently from the rewards\n function withdraw(uint256 amount) external nonReentrant whenNotPaused() {\n address _sender = _msgSender();\n\n _processRewards(_sender);\n _withdrawStake(_sender, amount);\n _updateContribution(_sender);\n }\n\n /// @notice withdraw the stake and the rewards from the contract\n function exit() external nonReentrant whenNotPaused() {\n address _sender = _msgSender();\n\n _processRewards(_sender);\n _withdrawStake(_sender, _balances[_sender]);\n _withdrawRewards(_sender);\n _updateContribution(_sender);\n emit Exit(_sender);\n }\n\n /// @notice withdraw the rewards from the contract\n /// @dev the user can withdraw his stake independently from the rewards\n function getReward() external nonReentrant whenNotPaused() {\n address _sender = _msgSender();\n\n _processRewards(_sender);\n _withdrawRewards(_sender);\n _updateContribution(_sender);\n }\n\n /// @notice as admin powers are really important in this contract\n /// we're overriding the renounceOwnership method to avoid losing rights\n function renounceOwnership() public view override onlyOwner {\n revert(\"ERC20RewardPool: can't renounceOwnership\");\n }\n\n function _withdrawStake(address account, uint256 amount) internal antiWithdrawCheck(_msgSender()) {\n require(amount > 0, \"ERC20RewardPool: Cannot withdraw 0\");\n super._withdraw(amount);\n emit Withdrawn(account, amount);\n }\n\n function _withdrawRewards(address account) internal timeLockClaimCheck(account) {\n uint256 reward = rewards[account];\n uint256 mod;\n if (reward > 0) {\n if (amountLockClaim.claimLockEnabled == true) {\n // constrain the reward amount to the integer allowed\n mod = reward % DECIMALS_18;\n reward -= mod;\n require(\n amountLockClaim.amount <= reward,\n \"ERC20RewardPool: Cannot withdraw - lockClaim.amount < reward\"\n );\n }\n require(reward <= getRewardsAvailable(), \"ERC20RewardPool: not enough rewards\");\n rewards[account] = mod;\n rewardToken.safeTransfer(account, reward);\n emit RewardPaid(account, reward);\n }\n }\n\n function _updateContribution(address account) internal {\n uint256 oldContribution = _contributions[account];\n _totalContributions -= oldContribution;\n uint256 contribution = _computeContribution(account);\n _totalContributions += contribution;\n _contributions[account] = contribution;\n emit ContributionUpdated(account, contribution, oldContribution);\n }\n\n function _computeContribution(address account) internal returns (uint256) {\n if (contributionRules == IContributionRules(address(0))) {\n return Math.min(_balances[account], maxStakeAllowedCalculator(account));\n } else {\n return\n contributionRules.computeMultiplier(\n account,\n Math.min(_balances[account], maxStakeAllowedCalculator(account))\n );\n }\n }\n\n // Something changed (stake, withdraw, etc), we distribute current accumulated rewards and start from zero.\n // Called each time there is a change in contract state (stake, withdraw, etc).\n function _processRewards(address account) internal {\n _restartRewards();\n _processAccountRewards(account);\n }\n\n // Update the earnings for this specific user with what he earned until now\n function _processAccountRewards(address account) internal {\n // usually _earned takes _rewardPerToken() but in this method is zero because _restartRewards must be\n // called before _processAccountRewards\n rewards[account] = rewards[account] + _earned(account, 0);\n // restart rewards for this specific user, now earned(account) = 0\n userRewardPerTokenPaid[account] = rewardPerTokenStored;\n }\n\n function _restartRewards() internal {\n if (rewardCalculator != IRewardCalculator(address(0))) {\n // Distribute the accumulated rewards\n rewardPerTokenStored = rewardPerTokenStored + _rewardPerToken();\n // restart rewards so now the rewardCalculator return zero rewards\n rewardCalculator.restartRewards();\n }\n }\n\n function _earned(address account, uint256 rewardPerToken_) internal view returns (uint256) {\n // - userRewardPerTokenPaid[account] * _contributions[account] / _totalContributions is the portion of\n // rewards the last time the user changed his contribution and called _restartRewards\n // (_totalContributions corresponds to previous value of that moment).\n // - rewardPerTokenStored * _contributions[account] is the share of the user from the\n // accumulated rewards (from the start of time until the last call to _restartRewards) with the\n // current value of _totalContributions\n // - _rewardPerToken() * _contributions[account] / _totalContributions is the share of the user of the\n // rewards from the last time anybody called _restartRewards until this moment\n //\n // The important thing to note is that at any moment in time _contributions[account] / _totalContributions is\n // the share of the user even if _totalContributions changes because of other users activity.\n return\n ((rewardPerToken_ + rewardPerTokenStored - userRewardPerTokenPaid[account]) * _contributions[account]) /\n 1e24;\n }\n\n // This function gives the proportion of the total contribution that corresponds to each user from\n // last restartRewards call.\n // _rewardsPerToken() * _contributions[account] is the amount of extra rewards gained from last restartRewards.\n function _rewardPerToken() internal view returns (uint256) {\n if (rewardCalculator == IRewardCalculator(address(0)) || _totalContributions == 0) {\n return 0;\n }\n return (rewardCalculator.getRewards() * 1e24) / _totalContributions;\n }\n\n /// @dev Triggers stopped state.\n /// The contract must not be paused.\n function pause() external onlyOwner {\n _pause();\n }\n\n /// @dev Returns to normal state.\n /// The contract must be paused.\n function unpause() external onlyOwner {\n _unpause();\n }\n\n function _msgSender() internal view override(Context, ERC2771HandlerV3) returns (address) {\n return ERC2771HandlerV3._msgSender();\n }\n\n function _msgData() internal view override(Context, ERC2771HandlerV3) returns (bytes calldata) {\n return ERC2771HandlerV3._msgData();\n }\n}\n" + }, + "src/solc_0.8/defi/interfaces/IContributionCalculator.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\n/// @title Plugins for the SandRewardPool that calculate the contributions must implement this interface\ninterface IContributionCalculator {\n /// @notice based on the user stake and address calculate the contribution\n /// @param account address of the user that is staking tokens\n /// @param amountStaked the amount of tokens stacked\n function computeContribution(address account, uint256 amountStaked) external returns (uint256);\n}\n" + }, + "src/solc_0.8/defi/interfaces/IContributionRules.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\n/// @title Plugins for the ERC20RewardPool that calculates the contributions (multipliers) must implement this interface\ninterface IContributionRules {\n /// @notice based on the user stake and address apply the contribution rules\n /// @param account address of the user that is staking tokens\n /// @param amountStaked the amount of tokens stacked\n function computeMultiplier(address account, uint256 amountStaked) external returns (uint256);\n}\n" + }, + "src/solc_0.8/defi/interfaces/IRewardCalculator.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\n/// @title Plugins for Reward Pools that calculate the rewards must implement this interface\ninterface IRewardCalculator {\n /// @dev At any point in time this function must return the accumulated rewards from the last call to restartRewards\n function getRewards() external view returns (uint256);\n\n /// @dev The main contract has distributed the rewards (getRewards()) until this point, this must start\n /// @dev from scratch => getRewards() == 0\n function restartRewards() external;\n}\n" + }, + "src/solc_0.8/defi/rewardCalculation/PeriodicRewardCalculator.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport {Math} from \"@openzeppelin/contracts-0.8/utils/math/Math.sol\";\nimport {AccessControl} from \"@openzeppelin/contracts-0.8/access/AccessControl.sol\";\nimport {IRewardCalculator} from \"../interfaces/IRewardCalculator.sol\";\n\n/*\n This contract calculate rewards linearly from the call to notifyRewardAmount until periodFinish\n if restartRewards is called in the middle with a nonzero contribution rewards are\n restarted (the main contract distribute the rewards at that point in time before calling)\n at the end of the period all the accumulated rewards (including those when restartRewards was called) are given.\n*/\ncontract PeriodicRewardCalculator is IRewardCalculator, AccessControl {\n event RewardAdded(uint256 reward);\n\n // This role is in charge of configuring reward distribution\n bytes32 public constant REWARD_DISTRIBUTION = keccak256(\"REWARD_DISTRIBUTION\");\n // Each time a parameter that affects the reward distribution is changed the rewards are distributed by the reward\n // pool contract this is the restart time.\n uint256 public lastUpdateTime;\n // This is the end of the period in which rewards are distributed\n uint256 public periodFinish;\n // Rewards are distributed at a fixed rate => reward = rewardRate * time\n uint256 public rewardRate;\n // The duration of the distribution period\n uint256 public duration;\n // This variable is only used when a new campaign starts (notifyRewardAmount is called)\n // We need to save the rewards accumulated between the last call to restartRewards and the call to notifyRewardAmount\n uint256 public savedRewards;\n // The address of the reward pool, the only one authorized to restart rewards\n address public immutable rewardPool;\n\n constructor(address rewardPool_, uint256 duration_) {\n rewardPool = rewardPool_;\n duration = duration_;\n _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());\n }\n\n function setDuration(uint256 newDuration) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), \"PeriodicRewardCalculator: not admin\");\n require(block.timestamp >= periodFinish, \"PeriodicRewardCalculator: campaign already started\");\n\n duration = newDuration;\n }\n\n // At any point in time this function must return the accumulated rewards from last call to restartRewards\n function getRewards() external view override returns (uint256) {\n return savedRewards + _getRewards();\n }\n\n // The main contract has distributed the rewards until this point, this must start from scratch => getRewards() == 0\n function restartRewards() external override {\n require(msg.sender == rewardPool, \"PeriodicRewardCalculator: not reward pool\");\n // ensure reward past the first stacker do not get lost\n lastUpdateTime = _lastTimeRewardApplicable();\n savedRewards = 0;\n }\n\n // Useful when switching reward calculators to set an initial reward.\n function setSavedRewards(uint256 reward) external {\n require(hasRole(REWARD_DISTRIBUTION, _msgSender()), \"PeriodicRewardCalculator: not reward distribution\");\n savedRewards = reward;\n lastUpdateTime = block.timestamp;\n }\n\n function lastTimeRewardApplicable() external view returns (uint256) {\n return _lastTimeRewardApplicable();\n }\n\n ///@notice to be called after the amount of reward tokens (specified by the reward parameter) has been sent to the contract\n // Note that the reward should be divisible by the duration to avoid reward token lost\n // When calling this function with remaining>0 then reward + leftover must be divisible by duration (which can be problematic)\n ///@param reward number of token to be distributed over the duration\n function notifyRewardAmount(uint256 reward) external {\n require(hasRole(REWARD_DISTRIBUTION, _msgSender()), \"PeriodicRewardCalculator: not reward distribution\");\n savedRewards = _getRewards();\n lastUpdateTime = block.timestamp;\n if (block.timestamp >= periodFinish) {\n rewardRate = reward / duration;\n } else {\n uint256 remaining = periodFinish - block.timestamp;\n uint256 leftover = remaining * rewardRate;\n rewardRate = (reward + leftover) / duration;\n }\n periodFinish = block.timestamp + duration;\n emit RewardAdded(reward);\n }\n\n function _getRewards() internal view returns (uint256) {\n return (_lastTimeRewardApplicable() - lastUpdateTime) * rewardRate;\n }\n\n function _lastTimeRewardApplicable() internal view returns (uint256) {\n return Math.min(block.timestamp, periodFinish);\n }\n}\n" + }, + "src/solc_0.8/defi/rewardCalculation/TwoPeriodsRewardCalculator.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport {Math} from \"@openzeppelin/contracts-0.8/utils/math/Math.sol\";\nimport {AccessControl} from \"@openzeppelin/contracts-0.8/access/AccessControl.sol\";\nimport {IRewardCalculator} from \"../interfaces/IRewardCalculator.sol\";\n\ncontract TwoPeriodsRewardCalculator is IRewardCalculator, AccessControl {\n event InitialCampaign(\n uint256 reward,\n uint256 duration,\n uint256 finish1,\n uint256 rate1,\n uint256 finish2,\n uint256 rate2\n );\n event NextCampaign(\n uint256 reward,\n uint256 duration,\n uint256 finish1,\n uint256 rate1,\n uint256 finish2,\n uint256 rate2\n );\n event UpdateCampaign(\n uint256 reward,\n uint256 duration,\n uint256 finish1,\n uint256 rate1,\n uint256 finish2,\n uint256 rate2\n );\n\n // This role is in charge of configuring reward distribution\n bytes32 public constant REWARD_DISTRIBUTION = keccak256(\"REWARD_DISTRIBUTION\");\n // Each time a parameter that affects the reward distribution is changed the rewards are distributed by the reward\n // pool contract this is the restart time.\n uint256 public lastUpdateTime;\n // This variable is only used when a new campaign starts (notifyRewardAmount is called)\n // We need to save the rewards accumulated between the last call to restartRewards and the call to notifyRewardAmount\n uint256 public savedRewards;\n // The reward distribution is divided in two periods with two different rated\n // | | |************|*\n // | | **| |*\n // | | ** | |*\n // | | ** | |*\n // | | ** | |*\n // | | ** | |*\n // | |** | |*\n // | ****| | |*\n // | **** | | |*\n // |**** | | |*\n // zero -> **********| | | |********************\n // |<-perido1-> |<-period2-> |<-restart-> |\n uint256 public finish1;\n uint256 public rate1;\n uint256 public finish2;\n uint256 public rate2;\n\n // The address of the reward pool, the only one authorized to restart rewards\n address public immutable rewardPool;\n\n constructor(address rewardPool_) {\n rewardPool = rewardPool_;\n _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());\n }\n\n // For the UI\n function getRate() external view returns (uint256) {\n return rate1;\n }\n\n // For the UI\n function getFinish() external view returns (uint256) {\n return finish1;\n }\n\n // At any point in time this function must return the accumulated rewards from last call to restartRewards\n function getRewards() external view override returns (uint256) {\n return savedRewards + _getRewards();\n }\n\n // The main contract has distributed the rewards until this point, this must start from scratch => getRewards() == 0\n function restartRewards() external override {\n require(msg.sender == rewardPool, \"not reward pool\");\n lastUpdateTime = block.timestamp;\n savedRewards = 0;\n }\n\n // Useful when switching reward calculators to set an initial reward.\n function setSavedRewards(uint256 reward) external {\n require(hasRole(REWARD_DISTRIBUTION, _msgSender()), \"not reward distribution\");\n savedRewards = reward;\n lastUpdateTime = block.timestamp;\n }\n\n // This is a helper function, it is better to call setInitialCampaign or updateNextCampaign directly\n function runCampaign(uint256 reward, uint256 duration) external {\n require(hasRole(REWARD_DISTRIBUTION, _msgSender()), \"not reward distribution\");\n if (block.timestamp >= finish2) {\n _initialCampaign(reward, duration);\n } else {\n _updateNextCampaign(reward, duration);\n }\n }\n\n // Start an initial campaign, set the period1 of reward distribution, period2 rate is zero\n function setInitialCampaign(uint256 reward, uint256 duration) external {\n require(hasRole(REWARD_DISTRIBUTION, _msgSender()), \"not reward distribution\");\n require(block.timestamp >= finish2, \"initial campaign running\");\n _initialCampaign(reward, duration);\n }\n\n // Update the period2 of rate distribution, must be called after an initial campaign is set\n // If period1 is running, period2 is set with the rate reward/duration.\n // If period1 is finished it is updated with the values of period2 and period2 is set with the rate reward/duration.\n function updateNextCampaign(uint256 reward, uint256 duration) external {\n require(hasRole(REWARD_DISTRIBUTION, _msgSender()), \"not reward distribution\");\n require(block.timestamp < finish2, \"initial campaign not running\");\n _updateNextCampaign(reward, duration);\n }\n\n function updateCurrentCampaign(uint256 reward, uint256 duration) external {\n require(hasRole(REWARD_DISTRIBUTION, _msgSender()), \"not reward distribution\");\n require(block.timestamp < finish2, \"initial campaign not running\");\n _updateCurrentCampaign(reward, duration);\n }\n\n // Check if both periods already ended => campaign is finished\n function isCampaignFinished() external view returns (bool) {\n return (block.timestamp >= finish2);\n }\n\n // Check if some of the periods are still running\n function isCampaignRunning() external view returns (bool) {\n return (block.timestamp < finish2);\n }\n\n function _initialCampaign(uint256 reward, uint256 duration) internal {\n // block.timestamp >= finish2\n _saveRewards();\n finish1 = block.timestamp + duration;\n rate1 = reward / duration;\n finish2 = block.timestamp + duration;\n rate2 = 0;\n emit InitialCampaign(reward, duration, finish1, rate1, finish2, rate2);\n }\n\n function _updateNextCampaign(uint256 reward, uint256 duration) internal {\n // block.timestamp < finish2\n _saveRewards();\n if (block.timestamp >= finish1) {\n // The next campaign is new.\n finish1 = finish2;\n rate1 = rate2;\n }\n finish2 = finish1 + duration;\n rate2 = reward / duration;\n emit NextCampaign(reward, duration, finish1, rate1, finish2, rate2);\n }\n\n // TODO: we need to check the logic for this one, what to do with the remainder rewards and the next campaign duration ?\n // TODO: Right now we restart the current campaign forgetting the old values and leaving next one untouched.\n function _updateCurrentCampaign(uint256 reward, uint256 duration) internal {\n _saveRewards();\n if (block.timestamp >= finish1) {\n // The next campaign is new.\n finish1 = finish2;\n rate1 = rate2;\n rate2 = 0;\n }\n assert(finish1 <= finish2);\n uint256 duration2 = finish2 - finish1;\n finish1 = block.timestamp + duration;\n finish2 = finish1 + duration2;\n rate1 = reward / duration;\n emit UpdateCampaign(reward, duration, finish1, rate1, finish2, rate2);\n }\n\n function _saveRewards() internal {\n savedRewards = savedRewards + _getRewards();\n lastUpdateTime = block.timestamp;\n }\n\n function _getRewards() internal view returns (uint256) {\n assert(lastUpdateTime <= block.timestamp);\n assert(finish1 <= finish2);\n if (lastUpdateTime >= finish2) {\n return 0;\n }\n if (block.timestamp <= finish1) {\n return (block.timestamp - lastUpdateTime) * rate1;\n }\n // block.timestamp > finish1\n uint256 rewards2 = (Math.min(block.timestamp, finish2) - Math.max(lastUpdateTime, finish1)) * rate2;\n if (lastUpdateTime < finish1) {\n // add reward1 + reward2\n return (finish1 - lastUpdateTime) * rate1 + rewards2;\n }\n return rewards2;\n }\n}\n" + }, + "src/solc_0.8/defi/rewardCalculation/TwoPeriodsRewardCalculatorV2.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport {Math} from \"@openzeppelin/contracts-0.8/utils/math/Math.sol\";\nimport {AccessControl} from \"@openzeppelin/contracts-0.8/access/AccessControl.sol\";\nimport {IRewardCalculator} from \"../interfaces/IRewardCalculator.sol\";\n\n/// @notice This contract has two periods and two corresponding rates and durations. After an initial call\n/// that sets the first period duration and rate another call can be done to set the duration and rate\n/// for the next period. When the first period finishes, the next period becomes the current one, and\n/// then the parameters for the future next period can be set again. This way the rate for the next\n/// period can be set at any moment.\ncontract TwoPeriodsRewardCalculatorV2 is IRewardCalculator, AccessControl {\n event InitialCampaign(\n uint256 reward,\n uint256 duration,\n uint256 finish1,\n uint256 rate1,\n uint256 finish2,\n uint256 rate2\n );\n event NextCampaign(\n uint256 reward,\n uint256 duration,\n uint256 finish1,\n uint256 rate1,\n uint256 finish2,\n uint256 rate2\n );\n event UpdateCampaign(\n uint256 reward,\n uint256 duration,\n uint256 finish1,\n uint256 rate1,\n uint256 finish2,\n uint256 rate2\n );\n\n event SavedRewardsSet(uint256 indexed reward);\n\n // This role is in charge of configuring reward distribution\n bytes32 public constant REWARD_DISTRIBUTION = keccak256(\"REWARD_DISTRIBUTION\");\n // Each time a parameter that affects the reward distribution is changed the rewards are distributed by the reward\n // pool contract this is the restart time.\n uint256 public lastUpdateTime;\n // This variable is only used when a new campaign starts (notifyRewardAmount is called)\n // We need to save the rewards accumulated between the last call to restartRewards and the call to notifyRewardAmount\n uint256 public savedRewards;\n // The reward distribution is divided in two periods with two different rated\n // | | |************|*\n // | | **| |*\n // | | ** | |*\n // | | ** | |*\n // | | ** | |*\n // | | ** | |*\n // | |** | |*\n // | ****| | |*\n // | **** | | |*\n // |**** | | |*\n // zero -> **********| | | |********************\n // |<-period1-> |<-period2-> |<-restart-> |\n uint256 public finish1;\n uint256 public rate1;\n uint256 public finish2;\n uint256 public rate2;\n\n // The address of the reward pool, the only one authorized to restart rewards\n address public immutable rewardPool;\n\n constructor(address rewardPool_) {\n rewardPool = rewardPool_;\n _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());\n }\n\n /// @notice For the UI\n function getRate() external view returns (uint256) {\n if (isCampaignFinished()) {\n return 0;\n } else if (block.timestamp >= finish1) {\n return rate2;\n } else {\n return rate1;\n }\n }\n\n /// @notice For the UI\n function getFinish() external view returns (uint256) {\n if (isCampaignFinished()) {\n return 0;\n } else if (block.timestamp >= finish1) {\n return finish2;\n } else {\n return finish1;\n }\n }\n\n /// @notice At any point in time this function must return the accumulated rewards from last call to restartRewards\n function getRewards() external view override returns (uint256) {\n return savedRewards + _getRewards();\n }\n\n /// @notice The main contract has distributed the rewards until this point, this must start from scratch => getRewards() == 0\n function restartRewards() external override {\n require(msg.sender == rewardPool, \"not reward pool\");\n lastUpdateTime = block.timestamp;\n savedRewards = 0;\n }\n\n /// @notice Useful when switching reward calculators to set an initial reward.\n function setSavedRewards(uint256 reward) external {\n require(hasRole(REWARD_DISTRIBUTION, _msgSender()), \"not reward distribution\");\n savedRewards = reward;\n lastUpdateTime = block.timestamp;\n\n emit SavedRewardsSet(reward);\n }\n\n /// @notice This is a helper function, it is better to call setInitialCampaign or updateNextCampaign directly\n function runCampaign(uint256 reward, uint256 duration) external {\n require(hasRole(REWARD_DISTRIBUTION, _msgSender()), \"not reward distribution\");\n if (block.timestamp >= finish2) {\n _initialCampaign(reward, duration);\n } else {\n _updateNextCampaign(reward, duration);\n }\n }\n\n /// @notice Start an initial campaign, set the period1 of reward distribution, period2 rate is zero\n function setInitialCampaign(uint256 reward, uint256 duration) external {\n require(hasRole(REWARD_DISTRIBUTION, _msgSender()), \"not reward distribution\");\n require(block.timestamp >= finish2, \"initial campaign running\");\n _initialCampaign(reward, duration);\n }\n\n /// @notice Update the period2 of rate distribution, must be called after an initial campaign is set\n /// If period1 is running, period2 is set with the rate reward/duration.\n /// If period1 is finished it is updated with the values of period2 and period2 is set with the rate reward/duration.\n function updateNextCampaign(uint256 reward, uint256 duration) external {\n require(hasRole(REWARD_DISTRIBUTION, _msgSender()), \"not reward distribution\");\n require(block.timestamp < finish2, \"initial campaign not running\");\n _updateNextCampaign(reward, duration);\n }\n\n /// @notice Update the period1 (current campaign) of rate distribution, must be called after an initial campaign is set\n function updateCurrentCampaign(uint256 reward, uint256 duration) external {\n require(hasRole(REWARD_DISTRIBUTION, _msgSender()), \"not reward distribution\");\n require(block.timestamp < finish2, \"initial campaign not running\");\n _updateCurrentCampaign(reward, duration);\n }\n\n // Check if both periods already ended => campaign is finished\n function isCampaignFinished() public view returns (bool) {\n return (block.timestamp >= finish2);\n }\n\n /// @notice Check if some of the periods are still running\n function isCampaignRunning() external view returns (bool) {\n return (block.timestamp < finish2);\n }\n\n function _initialCampaign(uint256 reward, uint256 duration) internal {\n // block.timestamp >= finish2\n _saveRewards();\n finish1 = block.timestamp + duration;\n rate1 = reward / duration;\n finish2 = block.timestamp + duration;\n rate2 = 0;\n emit InitialCampaign(reward, duration, finish1, rate1, finish2, rate2);\n }\n\n function _updateNextCampaign(uint256 reward, uint256 duration) internal {\n // block.timestamp < finish2\n _saveRewards();\n if (block.timestamp >= finish1) {\n // The next campaign is new.\n finish1 = finish2;\n rate1 = rate2;\n }\n finish2 = finish1 + duration;\n rate2 = reward / duration;\n emit NextCampaign(reward, duration, finish1, rate1, finish2, rate2);\n }\n\n // TODO: we need to check the logic for this one, what to do with the remainder rewards and the next campaign duration ?\n // TODO: Right now we restart the current campaign forgetting the old values and leaving next one untouched.\n function _updateCurrentCampaign(uint256 reward, uint256 duration) internal {\n _saveRewards();\n if (block.timestamp >= finish1) {\n // The next campaign is new.\n finish1 = finish2;\n rate1 = rate2;\n rate2 = 0;\n }\n assert(finish1 <= finish2);\n uint256 duration2 = finish2 - finish1;\n finish1 = block.timestamp + duration;\n finish2 = finish1 + duration2;\n rate1 = reward / duration;\n emit UpdateCampaign(reward, duration, finish1, rate1, finish2, rate2);\n }\n\n function _saveRewards() internal {\n savedRewards = savedRewards + _getRewards();\n lastUpdateTime = block.timestamp;\n }\n\n function _getRewards() internal view returns (uint256) {\n assert(lastUpdateTime <= block.timestamp);\n assert(finish1 <= finish2);\n if (lastUpdateTime >= finish2) {\n return 0;\n }\n if (block.timestamp <= finish1) {\n return (block.timestamp - lastUpdateTime) * rate1;\n }\n // block.timestamp > finish1\n uint256 rewards2 = (Math.min(block.timestamp, finish2) - Math.max(lastUpdateTime, finish1)) * rate2;\n if (lastUpdateTime < finish1) {\n // add reward1 + reward2\n return (finish1 - lastUpdateTime) * rate1 + rewards2;\n }\n return rewards2;\n }\n}\n" + }, + "src/solc_0.8/defi/rules-v2/ContributionRulesV2.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport {Ownable} from \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\nimport {Address} from \"@openzeppelin/contracts-0.8/utils/Address.sol\";\nimport {SafeMathWithRequire} from \"../../common/Libraries/SafeMathWithRequire.sol\";\nimport {IERC721} from \"@openzeppelin/contracts-0.8/token/ERC721/IERC721.sol\";\nimport {IERC1155} from \"@openzeppelin/contracts-0.8/token/ERC1155/IERC1155.sol\";\nimport {IContributionRules} from \"../interfaces/IContributionRules.sol\";\n\n/// @notice The contribution rules is a plugin contract that takes the amount staked and the address of\n/// the user and returns the absolute share (contribution) that the user will get from the total rewards.\n/// The contribution rules must implement the IContributionRules interface. This interface has only one method:\n/// computeMultiplier which takes the account and amountStaked parameters and returns the contribution for this user.\ncontract ContributionRulesV2 is Ownable, IContributionRules {\n using Address for address;\n\n // LIMITS\n // we limited the number of Ids and contracts that we can have in the lists\n // to avoid the risk of DoS caused by gas limits being exceeded during the iterations\n uint256 public constant IDS_LIMIT = 64;\n uint256 public constant CONTRACTS_LIMIT = 4;\n uint256 public constant MAX_MULTIPLIER = 1000;\n uint256 public multiplierLimitERC721 = 1000;\n uint256 public multiplierLimitERC1155 = 1000;\n\n uint256 internal constant DECIMALS_7 = 10_000_000;\n uint256 internal constant MIDPOINT_9 = 500_000_000;\n uint256 internal constant NFT_FACTOR_6 = 10000;\n uint256 internal constant NFT_CONSTANT_3 = 9000;\n uint256 internal constant ROOT3_FACTOR = 697;\n\n struct MultiplierRule {\n uint256[] ids;\n uint256[] multipliers;\n bool balanceOf;\n uint256 index;\n }\n\n mapping(IERC721 => MultiplierRule) internal _listERC721;\n mapping(IERC1155 => MultiplierRule) internal _listERC1155;\n IERC721[] internal _listERC721Index;\n IERC1155[] internal _listERC1155Index;\n\n event ERC1155MultiplierListSet(address indexed contractERC1155, uint256[] multipliers, uint256[] ids);\n event ERC721MultiplierListSet(address indexed contractERC721, uint256[] multipliers, uint256[] ids, bool balanceOf);\n event ERC1155MultiplierListDeleted(address indexed contractERC1155);\n event ERC721MultiplierListDeleted(address indexed contractERC721);\n event ERC721MultiplierLimitSet(uint256 newERC721MultiplierLimit);\n event ERC1155MultiplierLimitSet(uint256 newERC1155MultiplierLimit);\n\n modifier isContract(address account) {\n require(account.isContract(), \"ContributionRules: is not contract\");\n\n _;\n }\n\n modifier isERC721MemberList(address contractERC721) {\n require(\n isERC721MemberMultiplierList(IERC721(contractERC721)),\n \"ContributionRules: contract is not in the list\"\n );\n _;\n }\n\n modifier isERC1155MemberList(address contractERC1155) {\n require(\n isERC1155MemberMultiplierList(IERC1155(contractERC1155)),\n \"ContributionRules: contract is not in the list\"\n );\n _;\n }\n\n /// @notice compute user multiplier based on the amount staked\n /// @param account account to compute the multiplier\n /// @param amountStaked amount stake for the given account\n /// @return amountStaked\n function computeMultiplier(address account, uint256 amountStaked) external view override returns (uint256) {\n uint256 multiplierERC721 = multiplierBalanceOfERC721(account);\n uint256 multiplierERC1155 = multiplierBalanceOfERC1155(account);\n\n // check if the calculated multipliers exceed the limit\n if (multiplierLimitERC721 < multiplierERC721) {\n multiplierERC721 = multiplierLimitERC721;\n }\n\n if (multiplierLimitERC1155 < multiplierERC1155) {\n multiplierERC1155 = multiplierLimitERC1155;\n }\n\n return amountStaked + ((amountStaked * (multiplierERC721 + multiplierERC1155)) / 100);\n }\n\n /// @notice set a Multiplier limit a user can reach by having ERC721 tokens\n /// @param _newLimit new limit value - should be less then the max limit allowed by the system.\n function setERC721MultiplierLimit(uint256 _newLimit) external onlyOwner {\n require(_newLimit <= MAX_MULTIPLIER, \"ContributionRules: invalid newLimit\");\n\n multiplierLimitERC721 = _newLimit;\n\n emit ERC721MultiplierLimitSet(_newLimit);\n }\n\n /// @notice set a Multiplier limit a user can reach by having ERC1155 tokens\n /// @param _newLimit new limit value - should be less then the max limit allowed by the system.\n function setERC1155MultiplierLimit(uint256 _newLimit) external onlyOwner {\n require(_newLimit <= MAX_MULTIPLIER, \"ContributionRules: invalid newLimit\");\n\n multiplierLimitERC1155 = _newLimit;\n\n emit ERC1155MultiplierLimitSet(_newLimit);\n }\n\n /// @notice set the ERC1155 Multiplier list\n /// @param contractERC1155 ERC1155 contract address to add to the list\n /// @param ids ID user should hold to earn the multiplier\n /// @param multipliers multiplier applied if the user has the respective id\n function setERC1155MultiplierList(\n address contractERC1155,\n uint256[] memory ids,\n uint256[] memory multipliers\n ) external onlyOwner isContract(contractERC1155) {\n require(ids.length > 0, \"ContributionRules: ids <= 0\");\n require(ids.length <= IDS_LIMIT, \"ContributionRules: invalid array of ids\");\n require(multipliers.length > 0, \"ContributionRules: invalid array of multipliers\");\n require(multipliers.length == ids.length, \"ContributionRules: multipliers array != ids array\");\n\n IERC1155 multContract = IERC1155(contractERC1155);\n\n // if it's a new member create a new registry, instead, only update\n if (isERC1155MemberMultiplierList(multContract) == false) {\n // Limiting the size of the array (iterations) to avoid the risk of DoS.\n require(CONTRACTS_LIMIT > _listERC1155Index.length, \"ContributionRules: CONTRACTS_LIMIT exceeded\");\n _listERC1155Index.push(multContract);\n _listERC1155[multContract].index = _listERC1155Index.length - 1;\n }\n\n _listERC1155[multContract].ids = ids;\n _listERC1155[multContract].multipliers = multipliers;\n _listERC1155[multContract].balanceOf = false;\n\n emit ERC1155MultiplierListSet(contractERC1155, multipliers, ids);\n }\n\n /// @notice set the ERC721 Multiplier list\n /// @param contractERC721 ERC721 contract address to add to the list\n /// @param ids ID user should hold to earn the multiplier\n /// @param multipliers multiplier applied if the user has the respective id\n /// @param balanceOf if true, will use balanceOf instead of ID - id.length should be = 0\n function setERC721MultiplierList(\n address contractERC721,\n uint256[] memory ids,\n uint256[] memory multipliers,\n bool balanceOf\n ) external onlyOwner isContract(contractERC721) {\n if (balanceOf == false) {\n require(ids.length > 0, \"ContributionRules: invalid ids array\");\n require(multipliers.length == ids.length, \"ContributionRules: ids array != multipliers array\");\n }\n require(ids.length <= IDS_LIMIT, \"ContributionRules: invalid array of ids\");\n\n IERC721 multContract = IERC721(contractERC721);\n\n // if it's a new member create a new registry, instead, only update\n if (isERC721MemberMultiplierList(multContract) == false) {\n // Limiting the size of the array (iterations) to avoid the risk of DoS.\n require(CONTRACTS_LIMIT > _listERC721Index.length, \"ContributionRules: CONTRACTS_LIMIT exceeded\");\n _listERC721Index.push(multContract);\n _listERC721[multContract].index = _listERC721Index.length - 1;\n }\n\n _listERC721[multContract].multipliers = multipliers;\n _listERC721[multContract].balanceOf = balanceOf;\n _listERC721[multContract].ids = ids;\n\n emit ERC721MultiplierListSet(contractERC721, multipliers, ids, balanceOf);\n }\n\n /// @notice Return the max multiplier for the given account\n /// @param account account address to retrieve the max multiplier\n function getMaxGlobalMultiplier(address account) external view returns (uint256) {\n return multiplierBalanceOfERC721(account) + multiplierBalanceOfERC1155(account);\n }\n\n /// @notice return the ERC721 multiplier list for the given contract\n /// @param reqContract ERC721 contract address to retrieve\n function getERC721MultiplierList(address reqContract)\n external\n view\n isContract(reqContract)\n isERC721MemberList(reqContract)\n returns (MultiplierRule memory)\n {\n return _listERC721[IERC721(reqContract)];\n }\n\n /// @notice return the ERC1155 multiplier list for the given contract\n /// @param reqContract ERC1155 contract address to retrieve\n function getERC1155MultiplierList(address reqContract)\n external\n view\n isContract(reqContract)\n isERC1155MemberList(reqContract)\n returns (MultiplierRule memory)\n {\n return _listERC1155[IERC1155(reqContract)];\n }\n\n /// @notice remove the given contract from the list\n /// @param contractERC721 contract address to be removed from the list\n function deleteERC721MultiplierList(address contractERC721)\n external\n isContract(contractERC721)\n isERC721MemberList(contractERC721)\n onlyOwner\n {\n IERC721 reqContract = IERC721(contractERC721);\n uint256 indexToDelete = _listERC721[reqContract].index;\n IERC721 addrToMove = _listERC721Index[_listERC721Index.length - 1];\n _listERC721Index[indexToDelete] = addrToMove;\n _listERC721[addrToMove].index = indexToDelete;\n _listERC721Index.pop();\n\n emit ERC721MultiplierListDeleted(address(reqContract));\n }\n\n /// @notice remove the given contract from the list\n /// @param contractERC1155 contract address to be removed from the list\n function deleteERC1155MultiplierList(address contractERC1155)\n external\n isContract(contractERC1155)\n isERC1155MemberList(contractERC1155)\n onlyOwner\n {\n IERC1155 reqContract = IERC1155(contractERC1155);\n uint256 indexToDelete = _listERC1155[reqContract].index;\n IERC1155 addrToMove = _listERC1155Index[_listERC1155Index.length - 1];\n _listERC1155Index[indexToDelete] = addrToMove;\n _listERC1155[addrToMove].index = indexToDelete;\n _listERC1155Index.pop();\n\n emit ERC1155MultiplierListDeleted(address(reqContract));\n }\n\n /// @notice check if the given contract is in the list\n /// @param reqContract contract address to check\n /// @return true if the contract is in the list\n function isERC721MemberMultiplierList(IERC721 reqContract) public view returns (bool) {\n return !(_listERC721Index.length == 0) && (_listERC721Index[_listERC721[reqContract].index] == reqContract);\n }\n\n /// @notice check if the given contract is in the list\n /// @param reqContract contract address to check\n /// @return true if the contract is in the list\n function isERC1155MemberMultiplierList(IERC1155 reqContract) public view returns (bool) {\n return !(_listERC1155Index.length == 0) && (_listERC1155Index[_listERC1155[reqContract].index] == reqContract);\n }\n\n /// @notice calculate and return the ERC721 multiplier for a given user\n /// @param account user address to calculate the multiplier\n function multiplierBalanceOfERC721(address account) public view returns (uint256) {\n uint256 _multiplier;\n uint256 _indexLength = _listERC721Index.length;\n\n for (uint256 i; i < _indexLength; ) {\n IERC721 reqContract = _listERC721Index[i];\n\n if (_listERC721[reqContract].balanceOf == true) {\n _multiplier = _multiplier + multiplierLogarithm(account, reqContract);\n } else {\n uint256 _listIdsLength = _listERC721[reqContract].ids.length;\n for (uint256 j; j < _listIdsLength; ) {\n address owner = reqContract.ownerOf(_listERC721[reqContract].ids[j]);\n if (owner == account) {\n _multiplier = _multiplier + _listERC721[reqContract].multipliers[j];\n }\n\n unchecked {j++;}\n }\n }\n\n unchecked {i++;}\n }\n\n return _multiplier;\n }\n\n /// @notice calculate and return the ERC1155 multiplier for a given user\n /// @param account user address to calculate the multiplier\n function multiplierBalanceOfERC1155(address account) public view returns (uint256) {\n uint256 _multiplier;\n uint256 _indexLength = _listERC1155Index.length;\n\n for (uint256 i; i < _indexLength; ) {\n IERC1155 reqContract = _listERC1155Index[i];\n uint256 _listIdsLength = _listERC1155[reqContract].ids.length;\n\n for (uint256 j; j < _listIdsLength; ) {\n uint256 _bal = reqContract.balanceOf(account, _listERC1155[reqContract].ids[j]);\n\n if (_bal > 0) {\n _multiplier = _multiplier + _listERC1155[reqContract].multipliers[j];\n }\n\n unchecked {j++;}\n }\n\n unchecked {i++;}\n }\n\n return _multiplier;\n }\n\n /// @notice calculate and return the multiplier for a given user,\n /// based on the amount of the specific ERC721 he owns\n /// @param account user address to calculate the multiplier\n /// @param contractERC721 contract address to check\n /// @return ERC721 _multiplier based on the balance\n function multiplierLogarithm(address account, IERC721 contractERC721) public view returns (uint256) {\n uint256 balERC721 = contractERC721.balanceOf(account);\n\n if (balERC721 == 0) {\n return 0;\n }\n\n uint256 _multiplierERC721 =\n NFT_FACTOR_6 * (NFT_CONSTANT_3 + SafeMathWithRequire.cbrt3((((balERC721 - 1) * ROOT3_FACTOR) + 1)));\n if (_multiplierERC721 > MIDPOINT_9) {\n _multiplierERC721 = MIDPOINT_9 + (_multiplierERC721 - MIDPOINT_9) / 10;\n }\n\n return _multiplierERC721 / DECIMALS_7;\n }\n\n /// @notice as admin powers are really important in this contract\n /// we're overriding the renounceOwnership method to avoid losing rights\n function renounceOwnership() public view override onlyOwner {\n revert(\"ContributionRules: can't renounceOwnership\");\n }\n}\n" + }, + "src/solc_0.8/defi/rules-v2/LockRulesV2.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport {Context} from \"@openzeppelin/contracts-0.8/utils/Context.sol\";\nimport {Ownable} from \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\n\n// Note: this contract is meant to be inherited by ERC20RewardPool.\n// we should override the renounceOwnership() method otherwise.\n\n/// @notice The base contract (ERC20RewardPool) also inherits from this one. In this contract,\n/// we handle all the rules related to: Deposit, withdrawal, and claim. Basically, we have time locks for each action,\n/// where we can force the user to wait for a specific amount of time (lockPeriodInSecs) to re-do any of these actions.\n/// For the claim action, we also have the amountLockClaim(amount, bool). With this requirement,\n/// we can set a minimum amount to claim and also constrain the claim to an integer.\ncontract LockRulesV2 is Context, Ownable {\n // limits\n uint256 public constant TIME_LOCK_LIMIT = 180 days;\n uint256 public constant AMOUNT_LOCK_LIMIT = 1000 ether;\n\n struct TimeLockClaim {\n uint256 lockPeriodInSecs;\n mapping(address => uint256) lastClaim;\n }\n\n struct AmountLockClaim {\n uint256 amount;\n bool claimLockEnabled;\n }\n\n struct TimeLockWithdraw {\n uint256 lockPeriodInSecs;\n mapping(address => uint256) lastWithdraw;\n }\n\n struct TimeLockDeposit {\n uint256 lockPeriodInSecs;\n mapping(address => uint256) lastDeposit;\n }\n\n event TimelockClaimSet(uint256 lockPeriodInSecs);\n event TimelockDepositSet(uint256 newTimeDeposit);\n event TimeLockWithdrawSet(uint256 newTimeWithdraw);\n event AmountLockClaimSet(uint256 newAmountLockClaim, bool isEnabled);\n\n // This is used to implement a time buffer for reward retrieval, so the user cannot re-stake the rewards too fast.\n TimeLockClaim public timeLockClaim;\n AmountLockClaim public amountLockClaim;\n TimeLockWithdraw public lockWithdraw;\n TimeLockDeposit public lockDeposit;\n\n modifier timeLockClaimCheck(address account) {\n // We use lockPeriodInSecs == 0 to disable this check\n if (timeLockClaim.lockPeriodInSecs != 0) {\n require(\n block.timestamp > timeLockClaim.lastClaim[account] + timeLockClaim.lockPeriodInSecs,\n \"LockRules: Claim must wait\"\n );\n }\n timeLockClaim.lastClaim[account] = block.timestamp;\n _;\n }\n\n modifier antiWithdrawCheck(address account) {\n // We use lockPeriodInSecs == 0 to disable this check\n if (lockWithdraw.lockPeriodInSecs != 0) {\n require(\n block.timestamp > lockWithdraw.lastWithdraw[account] + lockWithdraw.lockPeriodInSecs,\n \"LockRules: Withdraw must wait\"\n );\n }\n lockWithdraw.lastWithdraw[account] = block.timestamp;\n _;\n }\n\n modifier antiDepositCheck(address account) {\n // We use lockPeriodInSecs == 0 to disable this check\n if (lockDeposit.lockPeriodInSecs != 0) {\n require(\n block.timestamp > lockDeposit.lastDeposit[account] + lockDeposit.lockPeriodInSecs,\n \"LockRules: Deposit must wait\"\n );\n }\n lockDeposit.lastDeposit[account] = block.timestamp;\n _;\n }\n\n /// @notice set the _lockPeriodInSecs for the anti-compound buffer\n /// @param _lockPeriodInSecs amount of time the user must wait between reward withdrawal\n function setTimelockClaim(uint256 _lockPeriodInSecs) external onlyOwner {\n require(_lockPeriodInSecs <= TIME_LOCK_LIMIT, \"LockRules: invalid lockPeriodInSecs\");\n timeLockClaim.lockPeriodInSecs = _lockPeriodInSecs;\n\n emit TimelockClaimSet(_lockPeriodInSecs);\n }\n\n /// @notice set a new time lock for the deposit\n /// user will only be able to stake again, after that time.\n /// @param _newTimeDeposit amount of time the user must wait between deposits/stake\n function setTimelockDeposit(uint256 _newTimeDeposit) external onlyOwner {\n require(_newTimeDeposit <= TIME_LOCK_LIMIT, \"LockRules: invalid lockPeriodInSecs\");\n lockDeposit.lockPeriodInSecs = _newTimeDeposit;\n\n emit TimelockDepositSet(_newTimeDeposit);\n }\n\n /// @notice set a new time lock for the withdrawn/unstake\n /// user will only be able to withdrawn/unstake again, after that time.\n /// @param _newTimeWithdraw amount of time the user must wait between withdrawn/unstake\n function setTimeLockWithdraw(uint256 _newTimeWithdraw) external onlyOwner {\n require(_newTimeWithdraw <= TIME_LOCK_LIMIT, \"LockRules: invalid lockPeriodInSecs\");\n lockWithdraw.lockPeriodInSecs = _newTimeWithdraw;\n\n emit TimeLockWithdrawSet(_newTimeWithdraw);\n }\n\n /// @notice set a new oamount lock for the claim\n /// user will only be able to claim rewards if the value is higher then the lock.\n /// @param _newAmountLockClaim min amount user should have to claim the rewards\n /// @param _isEnabled if true, the lock is enabled\n function setAmountLockClaim(uint256 _newAmountLockClaim, bool _isEnabled) external onlyOwner {\n require(_newAmountLockClaim <= AMOUNT_LOCK_LIMIT, \"LockRules: invalid newAmountLockClaim\");\n amountLockClaim.amount = _newAmountLockClaim;\n amountLockClaim.claimLockEnabled = _isEnabled;\n\n emit AmountLockClaimSet(_newAmountLockClaim, _isEnabled);\n }\n\n /// @notice return the remaining time for the user to be able to claim again\n function getRemainingTimelockClaim() external view returns (uint256) {\n uint256 timeLock = (timeLockClaim.lastClaim[_msgSender()] + timeLockClaim.lockPeriodInSecs);\n\n if (timeLock > block.timestamp) {\n return timeLock - block.timestamp;\n } else {\n return 0;\n }\n }\n\n /// @notice return the remaining time for the user to be able to withdrawn/unstake again\n function getRemainingTimelockWithdraw() external view returns (uint256) {\n uint256 timeLock = (lockWithdraw.lastWithdraw[_msgSender()] + lockWithdraw.lockPeriodInSecs);\n\n if (timeLock > block.timestamp) {\n return timeLock - block.timestamp;\n } else {\n return 0;\n }\n }\n\n /// @notice return the remaining time for the user to be able to deposit/stake again\n function getRemainingTimelockDeposit() external view returns (uint256) {\n uint256 timeLock = (lockDeposit.lastDeposit[_msgSender()] + lockDeposit.lockPeriodInSecs);\n\n if (timeLock > block.timestamp) {\n return timeLock - block.timestamp;\n } else {\n return 0;\n }\n }\n}\n" + }, + "src/solc_0.8/defi/rules-v2/RequirementsRulesV2.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport {Ownable} from \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\nimport {Address} from \"@openzeppelin/contracts-0.8/utils/Address.sol\";\nimport {Math} from \"@openzeppelin/contracts-0.8/utils/math/Math.sol\";\nimport {IERC721} from \"@openzeppelin/contracts-0.8/token/ERC721/IERC721.sol\";\nimport {IERC1155} from \"@openzeppelin/contracts-0.8/token/ERC1155/IERC1155.sol\";\n\n/// @notice The base contract (ERC20RewardPool) inherits from this one. This contract contains\n/// and checks all the requirements that a user needs to meet in order to stake.\n/// These requirements are checked through the modifier checkRequirements at the moment of the stake\ncontract RequirementsRulesV2 is Ownable {\n using Address for address;\n\n // we limited the number of Ids and contracts that we can have in the lists\n // to avoid the risk of DoS caused by gas limits being exceeded during the iterations\n uint256 public constant IDS_LIMIT = 64;\n uint256 public constant CONTRACTS_LIMIT = 4;\n\n // maxStake amount allowed if user has no ERC721 or ERC1155\n uint256 public maxStakeOverall;\n\n struct ERC721RequirementRule {\n uint256[] ids;\n bool balanceOf;\n uint256 minAmountBalanceOf;\n uint256 maxAmountBalanceOf;\n uint256 minAmountId;\n uint256 maxAmountId;\n uint256 index;\n }\n\n struct ERC1155RequirementRule {\n uint256[] ids;\n uint256 minAmountId;\n uint256 maxAmountId;\n uint256 index;\n }\n\n mapping(IERC721 => ERC721RequirementRule) internal _listERC721;\n mapping(IERC1155 => ERC1155RequirementRule) internal _listERC1155;\n IERC721[] internal _listERC721Index;\n IERC1155[] internal _listERC1155Index;\n\n event ERC1155RequirementListSet(\n address indexed contractERC1155,\n uint256[] ids,\n uint256 minAmountId,\n uint256 maxAmountId\n );\n event ERC721RequirementListSet(\n address indexed contractERC721,\n uint256[] ids,\n bool balanceOf,\n uint256 minAmountBalanceOf,\n uint256 maxAmountBalanceOf,\n uint256 minAmountId,\n uint256 maxAmountId\n );\n event MaxStakeOverallSet(uint256 newMaxStake, uint256 oldMaxStake);\n event ERC11551RequirementListDeleted(address indexed contractERC1155);\n event ERC721RequirementListDeleted(address indexed contractERC721);\n\n modifier isContract(address account) {\n require(account.isContract(), \"RequirementsRules: is not a contract\");\n\n _;\n }\n\n modifier checkRequirements(\n address account,\n uint256 amount,\n uint256 balanceOf\n ) {\n uint256 maxStakeERC721 = checkAndGetERC721Stake(account);\n uint256 maxStakeERC1155 = checkAndGetERC1155Stake(account);\n uint256 maxAllowed = _maxStakeAllowedCalculator(maxStakeERC721, maxStakeERC1155);\n\n if ((maxAllowed > 0) || _listERC721Index.length > 0 || _listERC1155Index.length > 0) {\n require(amount + balanceOf <= maxAllowed, \"RequirementsRules: maxAllowed\");\n }\n\n _;\n }\n\n modifier isERC721MemberList(address contractERC721) {\n require(\n isERC721MemberRequirementList(IERC721(contractERC721)),\n \"RequirementsRules: contract is not in the list\"\n );\n _;\n }\n\n modifier isERC1155MemberList(address contractERC1155) {\n require(\n isERC1155MemberRequirementList(IERC1155(contractERC1155)),\n \"RequirementsRules: contract is not in the list\"\n );\n _;\n }\n\n /// @notice set a Max stake in case user has not ERC721 or ERC1155\n /// @param newMaxStake new max stake value\n /// @dev we should always try setting this value to less than the lowest amount\n /// @dev possible from meeting a requirement rule.\n /// @dev That way we don't benefit those who do not have assets\n function setMaxStakeOverall(uint256 newMaxStake) external onlyOwner {\n uint256 oldMaxStake = maxStakeOverall;\n maxStakeOverall = newMaxStake;\n\n emit MaxStakeOverallSet(newMaxStake, oldMaxStake);\n }\n\n /// @notice set the ERC71 requirements for the user to stake\n /// @param contractERC721 ERC721 contract address to add to the list\n /// @param ids ID user should hold\n /// @param balanceOf if true, use the balanceOf values instead of Ids\n /// @param minAmountBalanceOf min amount user should hold to be able to stake\n /// @param maxAmountBalanceOf max value user can stake for each ERC721 he owns.\n /// @param minAmountId min amount user needs to own of a specific ID to be able to stake\n /// @param maxAmountId max value user can stake for each asset(ID) he owns\n function setERC721RequirementList(\n address contractERC721,\n uint256[] memory ids,\n bool balanceOf,\n uint256 minAmountBalanceOf,\n uint256 maxAmountBalanceOf,\n uint256 minAmountId,\n uint256 maxAmountId\n ) external onlyOwner isContract(contractERC721) {\n if (balanceOf == true) {\n require(ids.length == 0, \"RequirementRules: invalid ids array\");\n require(minAmountBalanceOf > 0, \"RequirementRules: invalid minAmountBalanceOf\");\n require(maxAmountBalanceOf > 0, \"RequirementRules: invalid maxAmountBalanceOf\");\n } else {\n require(ids.length > 0, \"RequirementRules: invalid ids array\");\n require(minAmountId > 0, \"RequirementRules: invalid minAmountId\");\n require(maxAmountId > 0, \"RequirementRules: invalid maxAmountId\");\n require(ids.length <= IDS_LIMIT, \"RequirementRules: ids array > limit\");\n }\n\n IERC721 newContract = IERC721(contractERC721);\n\n if (ids.length != 0) {\n _listERC721[newContract].ids = ids;\n }\n _listERC721[newContract].minAmountBalanceOf = minAmountBalanceOf;\n _listERC721[newContract].maxAmountBalanceOf = maxAmountBalanceOf;\n _listERC721[newContract].minAmountId = minAmountId;\n _listERC721[newContract].maxAmountId = maxAmountId;\n _listERC721[newContract].balanceOf = balanceOf;\n\n // if it's a new member create a new registry, instead, only update\n if (isERC721MemberRequirementList(newContract) == false) {\n // Limiting the size of the array (interations) to avoid the risk of DoS.\n require(CONTRACTS_LIMIT > _listERC721Index.length, \"RequirementsRules: CONTRACTS_LIMIT exceeded\");\n _listERC721Index.push(newContract);\n _listERC721[newContract].index = _listERC721Index.length - 1;\n }\n\n emit ERC721RequirementListSet(\n contractERC721,\n ids,\n balanceOf,\n minAmountBalanceOf,\n maxAmountBalanceOf,\n minAmountId,\n maxAmountId\n );\n }\n\n /// @notice set the ERC1155 requirements for the user to stake\n /// @param contractERC1155 ERC1155 contract address to add to the list\n /// @param ids ID user should hold\n /// @param minAmountId min amount user needs to own of a specific ID to be able to stake\n /// @param maxAmountId max value user can stake for each asset(ID) he owns\n function setERC1155RequirementList(\n address contractERC1155,\n uint256[] memory ids,\n uint256 minAmountId,\n uint256 maxAmountId\n ) external onlyOwner isContract(contractERC1155) {\n require(ids.length > 0, \"RequirementRules: invalid ids\");\n require(minAmountId > 0, \"RequirementRules: invalid minAmountId\");\n require(maxAmountId > 0, \"RequirementRules: invalid\");\n require(ids.length <= IDS_LIMIT, \"RequirementRules: IDS_LIMIT\");\n IERC1155 newContract = IERC1155(contractERC1155);\n _listERC1155[newContract].ids = ids;\n _listERC1155[newContract].minAmountId = minAmountId;\n _listERC1155[newContract].maxAmountId = maxAmountId;\n\n // if it's a new member create a new registry, instead, only update\n if (isERC1155MemberRequirementList(newContract) == false) {\n // Limiting the size of the array (interations) to avoid the risk of DoS.\n require(CONTRACTS_LIMIT > _listERC1155Index.length, \"RequirementsRules: CONTRACTS_LIMIT exceeded\");\n _listERC1155Index.push(newContract);\n _listERC1155[newContract].index = _listERC1155Index.length - 1;\n }\n\n emit ERC1155RequirementListSet(contractERC1155, ids, minAmountId, maxAmountId);\n }\n\n /// @notice return the ERC721 list of the given contract\n /// @param contractERC721 contract address to retrieve the list\n function getERC721RequirementList(address contractERC721)\n external\n view\n isContract(contractERC721)\n isERC721MemberList(contractERC721)\n returns (ERC721RequirementRule memory)\n {\n return _listERC721[IERC721(contractERC721)];\n }\n\n /// @notice return the ERC1155 list of the given contract\n /// @param contractERC1155 contract address to retrieve the list\n function getERC1155RequirementList(address contractERC1155)\n external\n view\n isContract(contractERC1155)\n isERC1155MemberList(contractERC1155)\n returns (ERC1155RequirementRule memory)\n {\n return _listERC1155[IERC1155(contractERC1155)];\n }\n\n /// @notice remove the given contract from the list\n /// @param contractERC721 contract address to be removed from the list\n function deleteERC721RequirementList(address contractERC721)\n external\n onlyOwner\n isContract(contractERC721)\n isERC721MemberList(contractERC721)\n {\n IERC721 reqContract = IERC721(contractERC721);\n uint256 indexToDelete = _listERC721[reqContract].index;\n IERC721 addrToMove = _listERC721Index[_listERC721Index.length - 1];\n _listERC721Index[indexToDelete] = addrToMove;\n _listERC721[addrToMove].index = indexToDelete;\n _listERC721Index.pop();\n\n emit ERC721RequirementListDeleted(contractERC721);\n }\n\n /// @notice remove the given contract from the list\n /// @param contractERC1155 contract address to be removed from the list\n function deleteERC1155RequirementList(address contractERC1155)\n external\n onlyOwner\n isContract(contractERC1155)\n isERC1155MemberList(contractERC1155)\n {\n IERC1155 reqContract = IERC1155(contractERC1155);\n uint256 indexToDelete = _listERC1155[reqContract].index;\n IERC1155 addrToMove = _listERC1155Index[_listERC1155Index.length - 1];\n _listERC1155Index[indexToDelete] = addrToMove;\n _listERC1155[addrToMove].index = indexToDelete;\n _listERC1155Index.pop();\n\n emit ERC11551RequirementListDeleted(contractERC1155);\n }\n\n /// @notice check if the given contract is in the list\n /// @param reqContract contract address to check\n /// @return true if the contract is in the list\n function isERC721MemberRequirementList(IERC721 reqContract) public view returns (bool) {\n return (_listERC721Index.length != 0) && (_listERC721Index[_listERC721[reqContract].index] == reqContract);\n }\n\n /// @notice check if the given contract is in the list\n /// @param reqContract contract address to check\n /// @return true if the contract is in the list\n function isERC1155MemberRequirementList(IERC1155 reqContract) public view returns (bool) {\n return (_listERC1155Index.length != 0) && (_listERC1155Index[_listERC1155[reqContract].index] == reqContract);\n }\n\n /// @notice return the max amount the user can stake for holding ERC721 assets\n /// @param account user address to calculate the max stake amount\n function getERC721MaxStake(address account) public view returns (uint256) {\n uint256 _maxStake;\n uint256 _indexLength = _listERC721Index.length;\n\n for (uint256 i; i < _indexLength; ) {\n uint256 balanceOf;\n uint256 balanceOfId;\n IERC721 reqContract = _listERC721Index[i];\n\n if (_listERC721[reqContract].balanceOf == true) {\n balanceOf = reqContract.balanceOf(account);\n } else {\n balanceOfId = getERC721BalanceId(reqContract, account);\n }\n\n _maxStake =\n _maxStake +\n (balanceOf *\n _listERC721[reqContract].maxAmountBalanceOf +\n balanceOfId *\n _listERC721[reqContract].maxAmountId);\n\n unchecked {i++;}\n }\n\n return _maxStake;\n }\n\n /// @notice return the max amount the user can stake for holding ERC1155 assets\n /// @param account user address to calculate the max stake amount\n function getERC1155MaxStake(address account) public view returns (uint256) {\n uint256 _maxStake;\n uint256 _indexLength = _listERC1155Index.length;\n\n for (uint256 i; i < _indexLength; ) {\n uint256 _totalBal;\n IERC1155 reqContract = _listERC1155Index[i];\n\n uint256 bal = getERC1155BalanceId(reqContract, account);\n\n _totalBal = _totalBal + bal;\n\n _maxStake = _maxStake + (_totalBal * _listERC1155[reqContract].maxAmountId);\n\n unchecked {i++;}\n }\n\n return _maxStake;\n }\n\n /// @notice return the max amount the user can stake\n /// @param account user address to calculate the max stake amount\n function maxStakeAllowedCalculator(address account) public view returns (uint256) {\n uint256 maxStakeERC721 = getERC721MaxStake(account);\n uint256 maxStakeERC1155 = getERC1155MaxStake(account);\n return _maxStakeAllowedCalculator(maxStakeERC721, maxStakeERC1155);\n }\n\n /// @notice return the balance of a specific ID the given user owns\n /// @param account user address to check the balance\n function getERC721BalanceId(IERC721 reqContract, address account) public view returns (uint256) {\n uint256 balanceOfId;\n uint256 _listIdsLength = _listERC721[reqContract].ids.length;\n\n for (uint256 j; j < _listIdsLength; ) {\n address owner = reqContract.ownerOf(_listERC721[reqContract].ids[j]);\n if (owner == account) {\n ++balanceOfId;\n }\n\n unchecked {j++;}\n }\n\n return balanceOfId;\n }\n\n /// @notice return the balance of a specific ID the given user owns\n /// @param account user address to check the balance\n function getERC1155BalanceId(IERC1155 reqContract, address account) public view returns (uint256) {\n uint256 balanceOfId;\n uint256 _listIdsLength = _listERC1155[reqContract].ids.length;\n\n for (uint256 j; j < _listIdsLength; ) {\n uint256 bal = reqContract.balanceOf(account, _listERC1155[reqContract].ids[j]);\n\n balanceOfId = balanceOfId + bal;\n\n unchecked {j++;}\n }\n\n return balanceOfId;\n }\n\n /// @notice check and calculates the ERC1155 max stake for the given user\n /// @param account user address to check\n function checkAndGetERC1155Stake(address account) public view returns (uint256) {\n uint256 _maxStake;\n uint256 _indexLength = _listERC1155Index.length;\n\n for (uint256 i; i < _indexLength; ) {\n IERC1155 reqContract = _listERC1155Index[i];\n\n uint256 balanceId = getERC1155BalanceId(reqContract, account);\n if (_listERC1155[reqContract].ids.length > 0) {\n require(balanceId >= _listERC1155[reqContract].minAmountId, \"RequirementsRules: balanceId\");\n }\n _maxStake = _maxStake + (balanceId * _listERC1155[reqContract].maxAmountId);\n\n unchecked {i++;}\n }\n return _maxStake;\n }\n\n /// @notice check and calculates the ERC721 max stake for the given user\n /// @param account user address to check\n function checkAndGetERC721Stake(address account) public view returns (uint256) {\n uint256 _maxStake;\n uint256 _indexLength = _listERC721Index.length;\n\n for (uint256 i; i < _indexLength; ) {\n uint256 balanceOf;\n uint256 balanceOfId;\n IERC721 reqContract = _listERC721Index[i];\n\n if (_listERC721[reqContract].balanceOf == true) {\n require(\n (reqContract.balanceOf(account) >= _listERC721[reqContract].minAmountBalanceOf) ||\n (maxStakeOverall > 0),\n \"RequirementsRules: balanceOf\"\n );\n balanceOf = reqContract.balanceOf(account);\n } else {\n balanceOfId = getERC721BalanceId(reqContract, account);\n if (_listERC721[reqContract].ids.length > 0) {\n require(\n (balanceOfId >= _listERC721[reqContract].minAmountId) || (maxStakeOverall > 0),\n \"RequirementsRules: balanceId\"\n );\n }\n }\n\n _maxStake =\n _maxStake +\n (balanceOf *\n _listERC721[reqContract].maxAmountBalanceOf +\n balanceOfId *\n _listERC721[reqContract].maxAmountId);\n\n unchecked {i++;}\n }\n return _maxStake;\n }\n\n /// @notice calculates the maxStake allowed\n /// @param maxStakeERC721 max stake ERC721 previously calculated for the user\n /// @param maxStakeERC1155 max stake ERC1155 previously calculated for the user\n /// @return max amount allowed for the user to stake\n function _maxStakeAllowedCalculator(uint256 maxStakeERC721, uint256 maxStakeERC1155)\n internal\n view\n returns (uint256)\n {\n uint256 maxAllowed = maxStakeOverall;\n\n uint256 totalMaxStake = maxStakeERC721 + maxStakeERC1155;\n\n if (totalMaxStake > 0) {\n if (maxAllowed > 0) {\n maxAllowed = Math.min(maxAllowed, totalMaxStake);\n } else {\n maxAllowed = totalMaxStake;\n }\n }\n\n return maxAllowed;\n }\n}\n" + }, + "src/solc_0.8/defi/rules/ContributionRules.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport {Ownable} from \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\nimport {Address} from \"@openzeppelin/contracts-0.8/utils/Address.sol\";\nimport {SafeMathWithRequire} from \"../../common/Libraries/SafeMathWithRequire.sol\";\nimport {IERC721} from \"@openzeppelin/contracts-0.8/token/ERC721/IERC721.sol\";\nimport {IERC1155} from \"@openzeppelin/contracts-0.8/token/ERC1155/IERC1155.sol\";\nimport {IContributionRules} from \"../interfaces/IContributionRules.sol\";\n\ncontract ContributionRules is Ownable, IContributionRules {\n using Address for address;\n\n // LIMITS\n // we limited the number of Ids and contracts that we can have in the lists\n // to avoid the risk of DoS caused by gas limits being exceeded during the iterations\n uint256 public constant idsLimit = 64;\n uint256 public constant contractsLimit = 4;\n uint256 public constant maxMultiplier = 1000;\n uint256 public multiplierLimitERC721 = 1000;\n uint256 public multiplierLimitERC1155 = 1000;\n\n uint256 internal constant DECIMALS_7 = 10_000_000;\n uint256 internal constant MIDPOINT_9 = 500_000_000;\n uint256 internal constant NFT_FACTOR_6 = 10000;\n uint256 internal constant NFT_CONSTANT_3 = 9000;\n uint256 internal constant ROOT3_FACTOR = 697;\n\n struct MultiplierRule {\n uint256[] ids;\n uint256[] multipliers;\n bool balanceOf;\n uint256 index;\n }\n\n mapping(IERC721 => MultiplierRule) internal _listERC721;\n mapping(IERC1155 => MultiplierRule) internal _listERC1155;\n IERC721[] internal _listERC721Index;\n IERC1155[] internal _listERC1155Index;\n\n event ERC1155MultiplierListSet(address indexed contractERC1155, uint256[] multipliers, uint256[] ids);\n event ERC721MultiplierListSet(address indexed contractERC721, uint256[] multipliers, uint256[] ids, bool balanceOf);\n event ERC1155MultiplierListDeleted(address indexed contractERC1155);\n event ERC721MultiplierListDeleted(address indexed contractERC721);\n event ERC721MultiplierLimitSet(uint256 newERC721MultiplierLimit);\n event ERC1155MultiplierLimitSet(uint256 newERC1155MultiplierLimit);\n\n modifier isContract(address account) {\n require(account.isContract(), \"ContributionRules: is not contract\");\n\n _;\n }\n\n modifier isERC721MemberList(address contractERC721) {\n require(\n isERC721MemberMultiplierList(IERC721(contractERC721)),\n \"ContributionRules: contract is not in the list\"\n );\n _;\n }\n\n modifier isERC1155MemberList(address contractERC1155) {\n require(\n isERC1155MemberMultiplierList(IERC1155(contractERC1155)),\n \"ContributionRules: contract is not in the list\"\n );\n _;\n }\n\n function computeMultiplier(address account, uint256 amountStaked) external view override returns (uint256) {\n uint256 multiplierERC721 = multiplierBalanceOfERC721(account);\n uint256 multiplierERC1155 = multiplierBalanceOfERC1155(account);\n\n // check if the calculated multipliers exceeds the limit\n if (multiplierLimitERC721 < multiplierERC721) {\n multiplierERC721 = multiplierLimitERC721;\n }\n\n if (multiplierLimitERC1155 < multiplierERC1155) {\n multiplierERC1155 = multiplierLimitERC1155;\n }\n\n return amountStaked + ((amountStaked * (multiplierERC721 + multiplierERC1155)) / 100);\n }\n\n function setERC721MultiplierLimit(uint256 _newLimit) external onlyOwner {\n require(_newLimit <= maxMultiplier, \"ContributionRules: invalid newLimit\");\n\n multiplierLimitERC721 = _newLimit;\n\n emit ERC721MultiplierLimitSet(_newLimit);\n }\n\n function setERC1155MultiplierLimit(uint256 _newLimit) external onlyOwner {\n require(_newLimit <= maxMultiplier, \"ContributionRules: invalid newLimit\");\n\n multiplierLimitERC1155 = _newLimit;\n\n emit ERC1155MultiplierLimitSet(_newLimit);\n }\n\n function setERC1155MultiplierList(\n address contractERC1155,\n uint256[] memory ids,\n uint256[] memory multipliers\n ) external onlyOwner isContract(contractERC1155) {\n require(ids.length > 0 && ids.length <= idsLimit, \"ContributionRules: invalid array of ids\");\n require(multipliers.length > 0, \"ContributionRules: invalid array of multipliers\");\n\n IERC1155 multContract = IERC1155(contractERC1155);\n\n // if it's a new member create a new registry, instead, only update\n if (isERC1155MemberMultiplierList(multContract) == false) {\n // Limiting the size of the array (interations) to avoid the risk of DoS.\n require(contractsLimit > _listERC1155Index.length, \"ContributionRules: contractsLimit exceeded\");\n _listERC1155Index.push(multContract);\n _listERC1155[multContract].index = _listERC1155Index.length - 1;\n }\n\n _listERC1155[multContract].ids = ids;\n _listERC1155[multContract].multipliers = multipliers;\n _listERC1155[multContract].balanceOf = false;\n\n emit ERC1155MultiplierListSet(contractERC1155, multipliers, ids);\n }\n\n function setERC721MultiplierList(\n address contractERC721,\n uint256[] memory ids,\n uint256[] memory multipliers,\n bool balanceOf\n ) external onlyOwner isContract(contractERC721) {\n require(\n balanceOf == true || (ids.length > 0 && multipliers.length == ids.length),\n \"ContributionRules: invalid list\"\n );\n require(ids.length <= idsLimit, \"ContributionRules: invalid array of ids\");\n\n IERC721 multContract = IERC721(contractERC721);\n\n // if it's a new member create a new registry, instead, only update\n if (isERC721MemberMultiplierList(multContract) == false) {\n // Limiting the size of the array (interations) to avoid the risk of DoS.\n require(contractsLimit > _listERC721Index.length, \"ContributionRules: contractsLimit exceeded\");\n _listERC721Index.push(multContract);\n _listERC721[multContract].index = _listERC721Index.length - 1;\n }\n\n _listERC721[multContract].multipliers = multipliers;\n _listERC721[multContract].balanceOf = balanceOf;\n _listERC721[multContract].ids = ids;\n\n emit ERC721MultiplierListSet(contractERC721, multipliers, ids, balanceOf);\n }\n\n function getMaxGlobalMultiplier(address account) external view returns (uint256) {\n return multiplierBalanceOfERC721(account) + multiplierBalanceOfERC1155(account);\n }\n\n function getERC721MultiplierList(address reqContract)\n external\n view\n isContract(reqContract)\n isERC721MemberList(reqContract)\n returns (MultiplierRule memory)\n {\n return _listERC721[IERC721(reqContract)];\n }\n\n function getERC1155MultiplierList(address reqContract)\n external\n view\n isContract(reqContract)\n isERC1155MemberList(reqContract)\n returns (MultiplierRule memory)\n {\n return _listERC1155[IERC1155(reqContract)];\n }\n\n function deleteERC721MultiplierList(address contractERC721)\n external\n isContract(contractERC721)\n isERC721MemberList(contractERC721)\n onlyOwner\n {\n IERC721 reqContract = IERC721(contractERC721);\n uint256 indexToDelete = _listERC721[reqContract].index;\n IERC721 addrToMove = _listERC721Index[_listERC721Index.length - 1];\n _listERC721Index[indexToDelete] = addrToMove;\n _listERC721[addrToMove].index = indexToDelete;\n _listERC721Index.pop();\n\n emit ERC721MultiplierListDeleted(address(reqContract));\n }\n\n function deleteERC1155MultiplierList(address contractERC1155)\n external\n isContract(contractERC1155)\n isERC1155MemberList(contractERC1155)\n onlyOwner\n {\n IERC1155 reqContract = IERC1155(contractERC1155);\n uint256 indexToDelete = _listERC1155[reqContract].index;\n IERC1155 addrToMove = _listERC1155Index[_listERC1155Index.length - 1];\n _listERC1155Index[indexToDelete] = addrToMove;\n _listERC1155[addrToMove].index = indexToDelete;\n _listERC1155Index.pop();\n\n emit ERC1155MultiplierListDeleted(address(reqContract));\n }\n\n function isERC721MemberMultiplierList(IERC721 reqContract) public view returns (bool) {\n return !(_listERC721Index.length == 0) && (_listERC721Index[_listERC721[reqContract].index] == reqContract);\n }\n\n function isERC1155MemberMultiplierList(IERC1155 reqContract) public view returns (bool) {\n return !(_listERC1155Index.length == 0) && (_listERC1155Index[_listERC1155[reqContract].index] == reqContract);\n }\n\n function multiplierBalanceOfERC721(address account) public view returns (uint256) {\n uint256 _multiplier = 0;\n\n for (uint256 i = 0; i < _listERC721Index.length; i++) {\n IERC721 reqContract = _listERC721Index[i];\n\n if (_listERC721[reqContract].balanceOf == true) {\n _multiplier = _multiplier + multiplierLogarithm(account, reqContract);\n } else {\n for (uint256 j = 0; j < _listERC721[reqContract].ids.length; j++) {\n address owner = reqContract.ownerOf(_listERC721[reqContract].ids[j]);\n if (owner == account) {\n _multiplier = _multiplier + _listERC721[reqContract].multipliers[j];\n }\n }\n }\n }\n\n return _multiplier;\n }\n\n function multiplierBalanceOfERC1155(address account) public view returns (uint256) {\n uint256 _multiplier = 0;\n for (uint256 i = 0; i < _listERC1155Index.length; i++) {\n IERC1155 reqContract = _listERC1155Index[i];\n\n for (uint256 j = 0; j < _listERC1155[reqContract].ids.length; j++) {\n uint256 _bal = reqContract.balanceOf(account, _listERC1155[reqContract].ids[j]);\n\n if (_bal > 0) {\n _multiplier = _multiplier + _listERC1155[reqContract].multipliers[j];\n }\n }\n }\n\n return _multiplier;\n }\n\n function multiplierLogarithm(address account, IERC721 contractERC721) public view returns (uint256) {\n uint256 balERC721 = contractERC721.balanceOf(account);\n\n if (balERC721 == 0) {\n return 0;\n }\n\n uint256 _multiplierERC721 =\n NFT_FACTOR_6 * (NFT_CONSTANT_3 + SafeMathWithRequire.cbrt3((((balERC721 - 1) * ROOT3_FACTOR) + 1)));\n if (_multiplierERC721 > MIDPOINT_9) {\n _multiplierERC721 = MIDPOINT_9 + (_multiplierERC721 - MIDPOINT_9) / 10;\n }\n\n return _multiplierERC721 / DECIMALS_7;\n }\n\n function renounceOwnership() public view override onlyOwner {\n revert(\"ContributionRules: can't renounceOwnership\");\n }\n}\n" + }, + "src/solc_0.8/defi/rules/LockRules.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport {Context} from \"@openzeppelin/contracts-0.8/utils/Context.sol\";\nimport {Ownable} from \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\n\n// Note: this contract is meant to be inherited by ERC20RewardPool.\n// we should override the renounceOwnership() method otherwise.\ncontract LockRules is Context, Ownable {\n // limits\n uint256 public constant timeLockLimit = 180 days;\n uint256 public constant amountLockLimit = 1000 ether;\n\n struct TimeLockClaim {\n uint256 lockPeriodInSecs;\n mapping(address => uint256) lastClaim;\n }\n\n struct AmountLockClaim {\n uint256 amount;\n bool claimLockEnabled;\n }\n\n struct TimeLockWithdraw {\n uint256 lockPeriodInSecs;\n mapping(address => uint256) lastWithdraw;\n }\n\n struct TimeLockDeposit {\n uint256 lockPeriodInSecs;\n mapping(address => uint256) lastDeposit;\n }\n\n event TimelockClaimSet(uint256 lockPeriodInSecs);\n event TimelockDepositSet(uint256 newTimeDeposit);\n event TimeLockWithdrawSet(uint256 newTimeWithdraw);\n event AmountLockClaimSet(uint256 newAmountLockClaim, bool isEnabled);\n\n // This is used to implement a time buffer for reward retrieval, so the user cannot re-stake the rewards too fast.\n TimeLockClaim public timeLockClaim;\n AmountLockClaim public amountLockClaim;\n TimeLockWithdraw public lockWithdraw;\n TimeLockDeposit public lockDeposit;\n\n modifier timeLockClaimCheck(address account) {\n // We use lockPeriodInSecs == 0 to disable this check\n if (timeLockClaim.lockPeriodInSecs != 0) {\n require(\n block.timestamp > timeLockClaim.lastClaim[account] + timeLockClaim.lockPeriodInSecs,\n \"LockRules: Claim must wait\"\n );\n }\n timeLockClaim.lastClaim[account] = block.timestamp;\n _;\n }\n\n modifier antiWithdrawCheck(address account) {\n // We use lockPeriodInSecs == 0 to disable this check\n if (lockWithdraw.lockPeriodInSecs != 0) {\n require(\n block.timestamp > lockWithdraw.lastWithdraw[account] + lockWithdraw.lockPeriodInSecs,\n \"LockRules: Withdraw must wait\"\n );\n }\n lockWithdraw.lastWithdraw[account] = block.timestamp;\n _;\n }\n\n modifier antiDepositCheck(address account) {\n // We use lockPeriodInSecs == 0 to disable this check\n if (lockDeposit.lockPeriodInSecs != 0) {\n require(\n block.timestamp > lockDeposit.lastDeposit[account] + lockDeposit.lockPeriodInSecs,\n \"LockRules: Deposit must wait\"\n );\n }\n lockDeposit.lastDeposit[account] = block.timestamp;\n _;\n }\n\n /// @notice set the _lockPeriodInSecs for the anti-compound buffer\n /// @param _lockPeriodInSecs amount of time the user must wait between reward withdrawal\n function setTimelockClaim(uint256 _lockPeriodInSecs) external onlyOwner {\n require(_lockPeriodInSecs <= timeLockLimit, \"LockRules: invalid lockPeriodInSecs\");\n timeLockClaim.lockPeriodInSecs = _lockPeriodInSecs;\n\n emit TimelockClaimSet(_lockPeriodInSecs);\n }\n\n function setTimelockDeposit(uint256 _newTimeDeposit) external onlyOwner {\n require(_newTimeDeposit <= timeLockLimit, \"LockRules: invalid lockPeriodInSecs\");\n lockDeposit.lockPeriodInSecs = _newTimeDeposit;\n\n emit TimelockDepositSet(_newTimeDeposit);\n }\n\n function setTimeLockWithdraw(uint256 _newTimeWithdraw) external onlyOwner {\n require(_newTimeWithdraw <= timeLockLimit, \"LockRules: invalid lockPeriodInSecs\");\n lockWithdraw.lockPeriodInSecs = _newTimeWithdraw;\n\n emit TimeLockWithdrawSet(_newTimeWithdraw);\n }\n\n function setAmountLockClaim(uint256 _newAmountLockClaim, bool _isEnabled) external onlyOwner {\n require(_newAmountLockClaim <= amountLockLimit, \"LockRules: invalid newAmountLockClaim\");\n amountLockClaim.amount = _newAmountLockClaim;\n amountLockClaim.claimLockEnabled = _isEnabled;\n\n emit AmountLockClaimSet(_newAmountLockClaim, _isEnabled);\n }\n\n function getRemainingTimelockClaim() external view returns (uint256) {\n uint256 timeLock = (timeLockClaim.lastClaim[_msgSender()] + timeLockClaim.lockPeriodInSecs);\n\n if (timeLock > block.timestamp) {\n return timeLock - block.timestamp;\n } else {\n return 0;\n }\n }\n\n function getRemainingTimelockWithdraw() external view returns (uint256) {\n uint256 timeLock = (lockWithdraw.lastWithdraw[_msgSender()] + lockWithdraw.lockPeriodInSecs);\n\n if (timeLock > block.timestamp) {\n return timeLock - block.timestamp;\n } else {\n return 0;\n }\n }\n\n function getRemainingTimelockDeposit() external view returns (uint256) {\n uint256 timeLock = (lockDeposit.lastDeposit[_msgSender()] + lockDeposit.lockPeriodInSecs);\n\n if (timeLock > block.timestamp) {\n return timeLock - block.timestamp;\n } else {\n return 0;\n }\n }\n}\n" + }, + "src/solc_0.8/defi/rules/RequirementsRules.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport {Ownable} from \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\nimport {Address} from \"@openzeppelin/contracts-0.8/utils/Address.sol\";\nimport {Math} from \"@openzeppelin/contracts-0.8/utils/math/Math.sol\";\nimport {IERC721} from \"@openzeppelin/contracts-0.8/token/ERC721/IERC721.sol\";\nimport {IERC1155} from \"@openzeppelin/contracts-0.8/token/ERC1155/IERC1155.sol\";\n\ncontract RequirementsRules is Ownable {\n using Address for address;\n\n // we limited the number of Ids and contracts that we can have in the lists\n // to avoid the risk of DoS caused by gas limits being exceeded during the iterations\n uint256 public idsLimit = 64;\n uint256 public contractsLimit = 4;\n\n // maxStake amount allowed if user has no ERC721 or ERC1155\n uint256 public maxStakeOverall;\n\n struct ERC721RequirementRule {\n uint256[] ids;\n bool balanceOf;\n uint256 minAmountBalanceOf;\n uint256 maxAmountBalanceOf;\n uint256 minAmountId;\n uint256 maxAmountId;\n uint256 index;\n }\n\n struct ERC1155RequirementRule {\n uint256[] ids;\n uint256 minAmountId;\n uint256 maxAmountId;\n uint256 index;\n }\n\n mapping(IERC721 => ERC721RequirementRule) internal _listERC721;\n mapping(IERC1155 => ERC1155RequirementRule) internal _listERC1155;\n IERC721[] internal _listERC721Index;\n IERC1155[] internal _listERC1155Index;\n\n event ERC1155RequirementListSet(\n address indexed contractERC1155,\n uint256[] ids,\n uint256 minAmountId,\n uint256 maxAmountId\n );\n event ERC721RequirementListSet(\n address indexed contractERC721,\n uint256[] ids,\n bool balanceOf,\n uint256 minAmountBalanceOf,\n uint256 maxAmountBalanceOf,\n uint256 minAmountId,\n uint256 maxAmountId\n );\n event MaxStakeOverallSet(uint256 newMaxStake, uint256 oldMaxStake);\n event ERC11551RequirementListDeleted(address indexed contractERC1155);\n event ERC721RequirementListDeleted(address indexed contractERC721);\n\n modifier isContract(address account) {\n require(account.isContract(), \"RequirementsRules: is not contract\");\n\n _;\n }\n\n modifier checkRequirements(\n address account,\n uint256 amount,\n uint256 balanceOf\n ) {\n uint256 maxStakeERC721 = checkAndGetERC721Stake(account);\n uint256 maxStakeERC1155 = checkAndGetERC1155Stake(account);\n uint256 maxAllowed = _maxStakeAllowedCalculator(maxStakeERC721, maxStakeERC1155);\n\n if ((maxAllowed > 0) || _listERC721Index.length > 0 || _listERC1155Index.length > 0) {\n require(amount + balanceOf <= maxAllowed, \"RequirementsRules: maxAllowed\");\n }\n\n _;\n }\n\n modifier isERC721MemberList(address contractERC721) {\n require(\n isERC721MemberRequirementList(IERC721(contractERC721)),\n \"RequirementsRules: contract is not in the list\"\n );\n _;\n }\n\n modifier isERC1155MemberList(address contractERC1155) {\n require(\n isERC1155MemberRequirementList(IERC1155(contractERC1155)),\n \"RequirementsRules: contract is not in the list\"\n );\n _;\n }\n\n // if user has not erc721 or erc1155\n function setMaxStakeOverall(uint256 newMaxStake) external onlyOwner {\n uint256 oldMaxStake = maxStakeOverall;\n maxStakeOverall = newMaxStake;\n\n emit MaxStakeOverallSet(newMaxStake, oldMaxStake);\n }\n\n function setERC721RequirementList(\n address contractERC721,\n uint256[] memory ids,\n bool balanceOf,\n uint256 minAmountBalanceOf,\n uint256 maxAmountBalanceOf,\n uint256 minAmountId,\n uint256 maxAmountId\n ) external onlyOwner isContract(contractERC721) {\n require(\n (balanceOf == true && ids.length == 0 && minAmountBalanceOf > 0 && maxAmountBalanceOf > 0) ||\n (balanceOf == false && ids.length > 0 && minAmountId > 0 && maxAmountId > 0 && ids.length <= idsLimit),\n \"RequirementRules: invalid list\"\n );\n IERC721 newContract = IERC721(contractERC721);\n\n if (ids.length != 0) {\n _listERC721[newContract].ids = ids;\n }\n _listERC721[newContract].minAmountBalanceOf = minAmountBalanceOf;\n _listERC721[newContract].maxAmountBalanceOf = maxAmountBalanceOf;\n _listERC721[newContract].minAmountId = minAmountId;\n _listERC721[newContract].maxAmountId = maxAmountId;\n _listERC721[newContract].balanceOf = balanceOf;\n\n // if it's a new member create a new registry, instead, only update\n if (isERC721MemberRequirementList(newContract) == false) {\n // Limiting the size of the array (interations) to avoid the risk of DoS.\n require(contractsLimit > _listERC721Index.length, \"RequirementsRules: contractsLimit exceeded\");\n _listERC721Index.push(newContract);\n _listERC721[newContract].index = _listERC721Index.length - 1;\n }\n\n emit ERC721RequirementListSet(\n contractERC721,\n ids,\n balanceOf,\n minAmountBalanceOf,\n maxAmountBalanceOf,\n minAmountId,\n maxAmountId\n );\n }\n\n function setERC1155RequirementList(\n address contractERC1155,\n uint256[] memory ids,\n uint256 minAmountId,\n uint256 maxAmountId\n ) external onlyOwner isContract(contractERC1155) {\n require(\n ids.length > 0 && minAmountId > 0 && maxAmountId > 0 && ids.length <= idsLimit,\n \"RequirementRules: invalid list\"\n );\n IERC1155 newContract = IERC1155(contractERC1155);\n _listERC1155[newContract].ids = ids;\n _listERC1155[newContract].minAmountId = minAmountId;\n _listERC1155[newContract].maxAmountId = maxAmountId;\n\n // if it's a new member create a new registry, instead, only update\n if (isERC1155MemberRequirementList(newContract) == false) {\n // Limiting the size of the array (interations) to avoid the risk of DoS.\n require(contractsLimit > _listERC1155Index.length, \"RequirementsRules: contractsLimit exceeded\");\n _listERC1155Index.push(newContract);\n _listERC1155[newContract].index = _listERC1155Index.length - 1;\n }\n\n emit ERC1155RequirementListSet(contractERC1155, ids, minAmountId, maxAmountId);\n }\n\n function getERC721RequirementList(address contractERC721)\n external\n view\n isContract(contractERC721)\n isERC721MemberList(contractERC721)\n returns (ERC721RequirementRule memory)\n {\n return _listERC721[IERC721(contractERC721)];\n }\n\n function getERC1155RequirementList(address contractERC1155)\n external\n view\n isContract(contractERC1155)\n isERC1155MemberList(contractERC1155)\n returns (ERC1155RequirementRule memory)\n {\n return _listERC1155[IERC1155(contractERC1155)];\n }\n\n function deleteERC721RequirementList(address contractERC721)\n external\n onlyOwner\n isContract(contractERC721)\n isERC721MemberList(contractERC721)\n {\n IERC721 reqContract = IERC721(contractERC721);\n uint256 indexToDelete = _listERC721[reqContract].index;\n IERC721 addrToMove = _listERC721Index[_listERC721Index.length - 1];\n _listERC721Index[indexToDelete] = addrToMove;\n _listERC721[addrToMove].index = indexToDelete;\n _listERC721Index.pop();\n\n emit ERC721RequirementListDeleted(contractERC721);\n }\n\n function deleteERC1155RequirementList(address contractERC1155)\n external\n onlyOwner\n isContract(contractERC1155)\n isERC1155MemberList(contractERC1155)\n {\n IERC1155 reqContract = IERC1155(contractERC1155);\n uint256 indexToDelete = _listERC1155[reqContract].index;\n IERC1155 addrToMove = _listERC1155Index[_listERC1155Index.length - 1];\n _listERC1155Index[indexToDelete] = addrToMove;\n _listERC1155[addrToMove].index = indexToDelete;\n _listERC1155Index.pop();\n\n emit ERC11551RequirementListDeleted(contractERC1155);\n }\n\n function isERC721MemberRequirementList(IERC721 reqContract) public view returns (bool) {\n return (_listERC721Index.length != 0) && (_listERC721Index[_listERC721[reqContract].index] == reqContract);\n }\n\n function isERC1155MemberRequirementList(IERC1155 reqContract) public view returns (bool) {\n return (_listERC1155Index.length != 0) && (_listERC1155Index[_listERC1155[reqContract].index] == reqContract);\n }\n\n function getERC721MaxStake(address account) public view returns (uint256) {\n uint256 _maxStake = 0;\n for (uint256 i = 0; i < _listERC721Index.length; i++) {\n uint256 balanceOf = 0;\n uint256 balanceOfId = 0;\n IERC721 reqContract = _listERC721Index[i];\n\n if (_listERC721[reqContract].balanceOf == true) {\n balanceOf = reqContract.balanceOf(account);\n } else {\n balanceOfId = getERC721BalanceId(reqContract, account);\n }\n\n _maxStake =\n _maxStake +\n (balanceOf *\n _listERC721[reqContract].maxAmountBalanceOf +\n balanceOfId *\n _listERC721[reqContract].maxAmountId);\n }\n\n return _maxStake;\n }\n\n function getERC1155MaxStake(address account) public view returns (uint256) {\n uint256 _maxStake = 0;\n\n for (uint256 i = 0; i < _listERC1155Index.length; i++) {\n uint256 _totalBal = 0;\n IERC1155 reqContract = _listERC1155Index[i];\n\n uint256 bal = getERC1155BalanceId(reqContract, account);\n\n _totalBal = _totalBal + bal;\n\n _maxStake = _maxStake + (_totalBal * _listERC1155[reqContract].maxAmountId);\n }\n\n return _maxStake;\n }\n\n function maxStakeAllowedCalculator(address account) public view returns (uint256) {\n uint256 maxStakeERC721 = getERC721MaxStake(account);\n uint256 maxStakeERC1155 = getERC1155MaxStake(account);\n return _maxStakeAllowedCalculator(maxStakeERC721, maxStakeERC1155);\n }\n\n function getERC721BalanceId(IERC721 reqContract, address account) public view returns (uint256) {\n uint256 balanceOfId = 0;\n\n for (uint256 j = 0; j < _listERC721[reqContract].ids.length; j++) {\n address owner = reqContract.ownerOf(_listERC721[reqContract].ids[j]);\n if (owner == account) {\n ++balanceOfId;\n }\n }\n\n return balanceOfId;\n }\n\n function getERC1155BalanceId(IERC1155 reqContract, address account) public view returns (uint256) {\n uint256 balanceOfId = 0;\n\n for (uint256 j = 0; j < _listERC1155[reqContract].ids.length; j++) {\n uint256 bal = reqContract.balanceOf(account, _listERC1155[reqContract].ids[j]);\n\n balanceOfId = balanceOfId + bal;\n }\n\n return balanceOfId;\n }\n\n function checkAndGetERC1155Stake(address account) public view returns (uint256) {\n uint256 _maxStake = 0;\n for (uint256 i = 0; i < _listERC1155Index.length; i++) {\n uint256 _totalBal = 0;\n IERC1155 reqContract = _listERC1155Index[i];\n\n uint256 balanceId = getERC1155BalanceId(reqContract, account);\n if (_listERC1155[reqContract].ids.length > 0) {\n require(balanceId >= _listERC1155[reqContract].minAmountId, \"RequirementsRules: balanceId\");\n }\n\n _totalBal = _totalBal + balanceId;\n _maxStake = _maxStake + (_totalBal * _listERC1155[reqContract].maxAmountId);\n }\n return _maxStake;\n }\n\n function checkAndGetERC721Stake(address account) public view returns (uint256) {\n uint256 _maxStake = 0;\n for (uint256 i = 0; i < _listERC721Index.length; i++) {\n uint256 balanceOf = 0;\n uint256 balanceOfId = 0;\n IERC721 reqContract = _listERC721Index[i];\n\n if (_listERC721[reqContract].balanceOf == true) {\n require(\n (reqContract.balanceOf(account) >= _listERC721[reqContract].minAmountBalanceOf) ||\n (maxStakeOverall > 0),\n \"RequirementsRules: balanceOf\"\n );\n balanceOf = reqContract.balanceOf(account);\n } else {\n balanceOfId = getERC721BalanceId(reqContract, account);\n if (_listERC721[reqContract].ids.length > 0) {\n require(\n (balanceOfId >= _listERC721[reqContract].minAmountId) || (maxStakeOverall > 0),\n \"RequirementsRules: balanceId\"\n );\n }\n }\n\n _maxStake =\n _maxStake +\n (balanceOf *\n _listERC721[reqContract].maxAmountBalanceOf +\n balanceOfId *\n _listERC721[reqContract].maxAmountId);\n }\n return _maxStake;\n }\n\n function _maxStakeAllowedCalculator(uint256 maxStakeERC721, uint256 maxStakeERC1155)\n internal\n view\n returns (uint256)\n {\n uint256 maxAllowed = maxStakeOverall;\n\n if (maxStakeERC721 + maxStakeERC1155 > 0) {\n if (maxStakeOverall > 0) {\n maxAllowed = Math.min(maxAllowed, maxStakeERC721 + maxStakeERC1155);\n } else {\n maxAllowed = maxStakeERC721 + maxStakeERC1155;\n }\n } else {\n maxAllowed = maxStakeOverall;\n }\n\n return maxAllowed;\n }\n}\n" + }, + "src/solc_0.8/defi/SandRewardPool.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport {Context} from \"@openzeppelin/contracts-0.8/utils/Context.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts-0.8/token/ERC20/utils/SafeERC20.sol\";\nimport {IERC20} from \"@openzeppelin/contracts-0.8/token/ERC20/IERC20.sol\";\nimport {ReentrancyGuard} from \"@openzeppelin/contracts-0.8/security/ReentrancyGuard.sol\";\nimport {Address} from \"@openzeppelin/contracts-0.8/utils/Address.sol\";\nimport {AccessControl} from \"@openzeppelin/contracts-0.8/access/AccessControl.sol\";\nimport {ERC2771Handler} from \"../common/BaseWithStorage/ERC2771Handler.sol\";\nimport {StakeTokenWrapper} from \"./StakeTokenWrapper.sol\";\nimport {IContributionCalculator} from \"./interfaces/IContributionCalculator.sol\";\nimport {IRewardCalculator} from \"./interfaces/IRewardCalculator.sol\";\n\n/// @title A pool that distributes rewards between users that stake sand (or any erc20 token)\n/// @notice The contributions are updated passively, an external call to computeContribution from a backend is needed.\n/// @notice After initialization the reward calculator must be set by the admin.\n/// @dev The contract has two plugins that affect the behaviour: contributionCalculator and rewardCalculator\n/// @dev contributionCalculator instead of using the stake directly the result of computeContribution is used\n/// @dev this way some users can get an extra share of the rewards\n/// @dev rewardCalculator is used to manage the rate at which the rewards are distributed.\n/// @dev This way we can build different types of pools by mixing in the plugins we want with this contract.\n/// @dev default behaviour (address(0)) for contributionCalculator is to use the stacked amount as contribution.\n/// @dev default behaviour (address(0)) for rewardCalculator is that no rewards are giving\ncontract SandRewardPool is StakeTokenWrapper, AccessControl, ReentrancyGuard, ERC2771Handler {\n using SafeERC20 for IERC20;\n using Address for address;\n\n event Staked(address indexed account, uint256 stakeAmount);\n event Withdrawn(address indexed account, uint256 stakeAmount);\n event Exit(address indexed account);\n event RewardPaid(address indexed account, uint256 rewardAmount);\n event ContributionUpdated(address indexed account, uint256 newContribution, uint256 oldContribution);\n\n // This value multiplied by the user contribution is the share of accumulated rewards (from the start of time\n // until the last call to restartRewards) for the user taking into account the value of totalContributions.\n uint256 public rewardPerTokenStored;\n\n // This value multiplied by the user contribution is the share of reward from the the last time\n // the user changed his contribution and called restartRewards\n mapping(address => uint256) public userRewardPerTokenPaid;\n\n // This value is the accumulated rewards won by the user when he called the contract.\n mapping(address => uint256) public rewards;\n\n IERC20 public rewardToken;\n IContributionCalculator public contributionCalculator;\n IRewardCalculator public rewardCalculator;\n\n uint256 internal _totalContributions;\n mapping(address => uint256) internal _contributions;\n\n struct AntiCompound {\n uint256 lockPeriodInSecs;\n mapping(address => uint256) lastClaim;\n }\n // This is used to implement a time buffer for reward retrieval, so the used cannot re-stake the rewards too fast.\n AntiCompound public antiCompound;\n\n constructor(\n IERC20 stakeToken_,\n IERC20 rewardToken_,\n address trustedForwarder\n ) StakeTokenWrapper(stakeToken_) {\n rewardToken = rewardToken_;\n _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());\n __ERC2771Handler_initialize(trustedForwarder);\n }\n\n modifier antiCompoundCheck(address account) {\n // We use lockPeriodInSecs == 0 to disable this check\n if (antiCompound.lockPeriodInSecs != 0) {\n require(\n block.timestamp > antiCompound.lastClaim[account] + antiCompound.lockPeriodInSecs,\n \"SandRewardPool: must wait\"\n );\n }\n antiCompound.lastClaim[account] = block.timestamp;\n _;\n }\n\n modifier isContractAndAdmin(address contractAddress) {\n require(contractAddress.isContract(), \"SandRewardPool: not a contract\");\n require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), \"SandRewardPool: not admin\");\n _;\n }\n\n /// @notice set the lockPeriodInSecs for the anti-compound buffer\n /// @param lockPeriodInSecs amount of time the user must wait between reward withdrawal\n function setAntiCompoundLockPeriod(uint256 lockPeriodInSecs) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), \"SandRewardPool: not admin\");\n antiCompound.lockPeriodInSecs = lockPeriodInSecs;\n }\n\n /// @notice set the contribution calculator\n /// @param contractAddress address of a plugin that calculates the contribution of the user based on his stake\n function setContributionCalculator(address contractAddress) external isContractAndAdmin(contractAddress) {\n contributionCalculator = IContributionCalculator(contractAddress);\n }\n\n /// @notice set the reward token\n /// @param contractAddress address token used to pay rewards\n function setRewardToken(address contractAddress) external isContractAndAdmin(contractAddress) {\n rewardToken = IERC20(contractAddress);\n }\n\n /// @notice set the stake token\n /// @param contractAddress address token used to stake funds\n function setStakeToken(address contractAddress) external isContractAndAdmin(contractAddress) {\n _stakeToken = IERC20(contractAddress);\n }\n\n /// @notice set the trusted forwarder\n /// @param trustedForwarder address of the contract that is enabled to send meta-tx on behalf of the user\n function setTrustedForwarder(address trustedForwarder) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), \"SandRewardPool: not admin\");\n _trustedForwarder = trustedForwarder;\n }\n\n /// @notice set the reward calculator\n /// @param contractAddress address of a plugin that calculates absolute rewards at any point in time\n /// @param restartRewards if true the rewards from the previous calculator are accumulated before changing it\n function setRewardCalculator(address contractAddress, bool restartRewards)\n external\n isContractAndAdmin(contractAddress)\n {\n // We process the rewards of the current reward calculator before the switch.\n if (restartRewards) {\n _restartRewards();\n }\n rewardCalculator = IRewardCalculator(contractAddress);\n }\n\n /// @notice the admin recover is able to recover reward funds\n /// @param receiver address of the beneficiary of the recovered funds\n /// @dev this function must be called in an emergency situation only.\n /// @dev Calling it is risky specially when rewardToken == stakeToken\n function recoverFunds(address receiver) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), \"SandRewardPool: not admin\");\n require(receiver != address(0), \"SandRewardPool: invalid receiver\");\n rewardToken.safeTransfer(receiver, rewardToken.balanceOf(address(this)));\n }\n\n /// @notice return the total supply of staked tokens\n /// @return the total supply of staked tokens\n function totalSupply() external view returns (uint256) {\n return _totalSupply;\n }\n\n /// @notice return the balance of staked tokens for a user\n /// @param account the address of the account\n /// @return balance of staked tokens\n function balanceOf(address account) external view returns (uint256) {\n return _balances[account];\n }\n\n /// @notice return the address of the stake token contract\n /// @return address of the stake token contract\n function stakeToken() external view returns (IERC20) {\n return _stakeToken;\n }\n\n /// @notice return the amount of rewards deposited in the contract that can be distributed by different campaigns\n /// @return the total amount of deposited rewards\n /// @dev this function can be called by a reward calculator to throw if a campaign doesn't have\n /// @dev enough rewards to start\n function getRewardsAvailable() external view returns (uint256) {\n if (address(rewardToken) != address(_stakeToken)) {\n return rewardToken.balanceOf(address(this));\n }\n return _stakeToken.balanceOf(address(this)) - _totalSupply;\n }\n\n /// @notice return the sum of the values returned by the contribution calculator\n /// @return total contributions of the users\n /// @dev this is the same than the totalSupply only if the contribution calculator\n /// @dev uses the staked amount as the contribution of the user which is the default behaviour\n function totalContributions() external view returns (uint256) {\n return _totalContributions;\n }\n\n /// @notice return the contribution of some user\n /// @param account the address of the account\n /// @return contribution of the users\n /// @dev this is the same than the balanceOf only if the contribution calculator\n /// @dev uses the staked amount as the contribution of the user which is the default behaviour\n function contributionOf(address account) external view returns (uint256) {\n return _contributions[account];\n }\n\n /// @notice accumulated rewards taking into account the totalContribution (see: rewardPerTokenStored)\n /// @return the accumulated total rewards\n /// @dev This value multiplied by the user contribution is the share of accumulated rewards for the user. Taking\n /// @dev into account the value of totalContributions.\n function rewardPerToken() external view returns (uint256) {\n return rewardPerTokenStored + _rewardPerToken();\n }\n\n /// @notice available earnings for some user\n /// @param account the address of the account\n /// @return the available earnings for the user\n function earned(address account) external view returns (uint256) {\n return rewards[account] + _earned(account, _rewardPerToken());\n }\n\n /// @notice accumulates the current rewards into rewardPerTokenStored and restart the reward calculator\n /// @dev calling this function make no difference. It is useful for testing and when the reward calculator\n /// @dev is changed.\n function restartRewards() external {\n _restartRewards();\n }\n\n /// @notice update the contribution for a user\n /// @param account the address of the account\n /// @dev if the user change his holdings (or any other parameter that affect the contribution calculation),\n /// @dev he can the reward distribution to his favor. This function must be called by an external agent ASAP to\n /// @dev update the contribution for the user. We understand the risk but the rewards are distributes slowly so\n /// @dev the user cannot affect the reward distribution heavily.\n function computeContribution(address account) external {\n require(account != address(0), \"SandRewardPool: invalid address\");\n // We decide to give the user the accumulated rewards even if he cheated a little bit.\n _processRewards(account);\n _updateContribution(account);\n }\n\n /// @notice update the contribution for a sef of users\n /// @param accounts the addresses of the accounts to update\n /// @dev see: computeContribution\n function computeContributionInBatch(address[] calldata accounts) external {\n _restartRewards();\n for (uint256 i = 0; i < accounts.length; i++) {\n address account = accounts[i];\n if (account == address(0)) {\n continue;\n }\n _processAccountRewards(account);\n _updateContribution(account);\n }\n }\n\n /// @notice stake some amount into the contract\n /// @param amount the amount of tokens to stake\n /// @dev the user must approve in the stack token before calling this function\n function stake(uint256 amount) external nonReentrant {\n require(amount > 0, \"SandRewardPool: Cannot stake 0\");\n\n // The first time a user stakes he cannot remove his rewards immediately.\n if (antiCompound.lastClaim[_msgSender()] == 0) {\n antiCompound.lastClaim[_msgSender()] = block.timestamp;\n }\n\n uint256 earlierRewards = 0;\n\n if (_totalContributions == 0 && rewardCalculator != IRewardCalculator(address(0))) {\n earlierRewards = rewardCalculator.getRewards();\n }\n\n _processRewards(_msgSender());\n super._stake(amount);\n _updateContribution(_msgSender());\n require(_contributions[_msgSender()] > 0, \"SandRewardPool: not enough contributions\");\n\n if (earlierRewards != 0) {\n rewards[_msgSender()] = rewards[_msgSender()] + earlierRewards;\n }\n emit Staked(_msgSender(), amount);\n }\n\n /// @notice withdraw the stake from the contract\n /// @param amount the amount of tokens to withdraw\n /// @dev the user can withdraw his stake independently from the rewards\n function withdraw(uint256 amount) external nonReentrant {\n _processRewards(_msgSender());\n _withdrawStake(_msgSender(), amount);\n _updateContribution(_msgSender());\n }\n\n /// @notice withdraw the stake and the rewards from the contract\n function exit() external nonReentrant {\n _processRewards(_msgSender());\n _withdrawStake(_msgSender(), _balances[_msgSender()]);\n _withdrawRewards(_msgSender());\n _updateContribution(_msgSender());\n emit Exit(_msgSender());\n }\n\n /// @notice withdraw the rewards from the contract\n /// @dev the user can withdraw his stake independently from the rewards\n function getReward() external nonReentrant {\n _processRewards(_msgSender());\n _withdrawRewards(_msgSender());\n _updateContribution(_msgSender());\n }\n\n function _withdrawStake(address account, uint256 amount) internal {\n require(amount > 0, \"SandRewardPool: Cannot withdraw 0\");\n super._withdraw(amount);\n emit Withdrawn(account, amount);\n }\n\n function _withdrawRewards(address account) internal antiCompoundCheck(account) {\n uint256 reward = rewards[account];\n if (reward > 0) {\n rewards[account] = 0;\n rewardToken.safeTransfer(account, reward);\n emit RewardPaid(account, reward);\n }\n }\n\n function _updateContribution(address account) internal {\n uint256 oldContribution = _contributions[account];\n _totalContributions = _totalContributions - oldContribution;\n uint256 contribution = _computeContribution(account);\n _totalContributions = _totalContributions + contribution;\n _contributions[account] = contribution;\n emit ContributionUpdated(account, contribution, oldContribution);\n }\n\n function _computeContribution(address account) internal returns (uint256) {\n if (contributionCalculator == IContributionCalculator(address(0))) {\n return _balances[account];\n } else {\n return contributionCalculator.computeContribution(account, _balances[account]);\n }\n }\n\n // Something changed (stake, withdraw, etc), we distribute current accumulated rewards and start from zero.\n // Called each time there is a change in contract state (stake, withdraw, etc).\n function _processRewards(address account) internal {\n _restartRewards();\n _processAccountRewards(account);\n }\n\n // Update the earnings for this specific user with what he earned until now\n function _processAccountRewards(address account) internal {\n // usually _earned takes _rewardPerToken() but in this method is zero because _restartRewards must be\n // called before _processAccountRewards\n rewards[account] = rewards[account] + _earned(account, 0);\n // restart rewards for this specific user, now earned(account) = 0\n userRewardPerTokenPaid[account] = rewardPerTokenStored;\n }\n\n function _restartRewards() internal {\n if (rewardCalculator != IRewardCalculator(address(0))) {\n // Distribute the accumulated rewards\n rewardPerTokenStored = rewardPerTokenStored + _rewardPerToken();\n // restart rewards so now the rewardCalculator return zero rewards\n rewardCalculator.restartRewards();\n }\n }\n\n function _earned(address account, uint256 rewardPerToken) internal view returns (uint256) {\n // - userRewardPerTokenPaid[account] * _contributions[account] / _totalContributions is the portion of\n // rewards the last time the user changed his contribution and called _restartRewards\n // (_totalContributions corresponds to previous value of that moment).\n // - rewardPerTokenStored * _contributions[account] is the share of the user from the\n // accumulated rewards (from the start of time until the last call to _restartRewards) with the\n // current value of _totalContributions\n // - _rewardPerToken() * _contributions[account] / _totalContributions is the share of the user of the\n // rewards from the last time anybody called _restartRewards until this moment\n //\n // The important thing to note is that at any moment in time _contributions[account] / _totalContributions is\n // the share of the user even if _totalContributions changes because of other users activity.\n return\n ((rewardPerToken + rewardPerTokenStored - userRewardPerTokenPaid[account]) * _contributions[account]) /\n 1e24;\n }\n\n // This function gives the proportion of the total contribution that corresponds to each user from\n // last restartRewards call.\n // _rewardsPerToken() * _contributions[account] is the amount of extra rewards gained from last restartRewards.\n function _rewardPerToken() internal view returns (uint256) {\n if (rewardCalculator == IRewardCalculator(address(0)) || _totalContributions == 0) {\n return 0;\n }\n return (rewardCalculator.getRewards() * 1e24) / _totalContributions;\n }\n\n function _msgSender() internal view override(Context, ERC2771Handler) returns (address sender) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view override(Context, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n}\n" + }, + "src/solc_0.8/defi/StakeTokenWrapper.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/utils/Context.sol\";\nimport \"@openzeppelin/contracts-0.8/token/ERC20/utils/SafeERC20.sol\";\nimport {Address} from \"@openzeppelin/contracts-0.8/utils/Address.sol\";\n\nabstract contract StakeTokenWrapper is Context {\n using Address for address;\n using SafeERC20 for IERC20;\n IERC20 internal _stakeToken;\n\n uint256 internal _totalSupply;\n mapping(address => uint256) internal _balances;\n\n constructor(IERC20 stakeToken) {\n require(address(stakeToken).isContract(), \"StakeTokenWrapper: is not a contract\");\n _stakeToken = stakeToken;\n }\n\n function _stake(uint256 amount) internal virtual {\n require(amount > 0, \"StakeTokenWrapper: amount > 0\");\n _totalSupply = _totalSupply + amount;\n _balances[_msgSender()] = _balances[_msgSender()] + amount;\n _stakeToken.safeTransferFrom(_msgSender(), address(this), amount);\n }\n\n function _withdraw(uint256 amount) internal virtual {\n require(amount > 0, \"StakeTokenWrapper: amount > 0\");\n _totalSupply = _totalSupply - amount;\n _balances[_msgSender()] = _balances[_msgSender()] - amount;\n _stakeToken.safeTransfer(_msgSender(), amount);\n }\n\n uint256[50] private __gap;\n}\n" + }, + "src/solc_0.8/defi/StakeTokenWrapperV2.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport {Context} from \"@openzeppelin/contracts-0.8/utils/Context.sol\";\nimport {SafeERC20, IERC20} from \"@openzeppelin/contracts-0.8/token/ERC20/utils/SafeERC20.sol\";\nimport {Address} from \"@openzeppelin/contracts-0.8/utils/Address.sol\";\n\n/// @title Token wrapper contract to be used by the staking pools\nabstract contract StakeTokenWrapperV2 is Context {\n using Address for address;\n using SafeERC20 for IERC20;\n IERC20 internal _stakeToken;\n\n uint256 internal _totalSupply;\n mapping(address => uint256) internal _balances;\n\n constructor(IERC20 stakeToken) {\n require(address(stakeToken).isContract(), \"StakeTokenWrapper: is not a contract\");\n _stakeToken = stakeToken;\n }\n\n function _stake(uint256 amount) internal virtual {\n require(amount > 0, \"StakeTokenWrapper: amount > 0\");\n\n address _sender = _msgSender();\n\n _totalSupply += amount;\n _balances[_sender] += amount;\n _stakeToken.safeTransferFrom(_sender, address(this), amount);\n }\n\n function _withdraw(uint256 amount) internal virtual {\n require(amount > 0, \"StakeTokenWrapper: amount > 0\");\n\n address _sender = _msgSender();\n\n _totalSupply -= amount;\n _balances[_sender] -= amount;\n _stakeToken.safeTransfer(_sender, amount);\n }\n}\n" + }, + "src/solc_0.8/faucet/Faucet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\nimport \"@openzeppelin/contracts-0.8/utils/Strings.sol\";\n\ncontract Faucet is Ownable {\n IERC20 internal immutable _ierc20;\n uint256 internal _period;\n uint256 internal _amountLimit;\n\n mapping(address => uint256) public _lastTimestamps;\n\n constructor(\n IERC20 ierc20,\n uint256 period,\n uint256 amountLimit\n ) {\n _ierc20 = ierc20;\n _period = period;\n _amountLimit = amountLimit;\n }\n\n event FaucetPeriod(uint256 period);\n event FaucetLimit(uint256 amountLimit);\n event FaucetSent(address _receiver, uint256 _amountSent);\n event FaucetRetrieved(address receiver, uint256 _amountSent);\n\n /// @notice set the minimum time delta between 2 calls to send() for an address.\n /// @param period time delta between 2 calls to send() for an address.\n function setPeriod(uint256 period) public onlyOwner {\n _period = period;\n emit FaucetPeriod(period);\n }\n\n /// @notice returns the minimum time delta between 2 calls to Send for an address.\n function getPeriod() public view returns (uint256) {\n return _period;\n }\n\n /// @notice return the maximum IERC20 token amount for an address.\n function setLimit(uint256 amountLimit) public onlyOwner {\n _amountLimit = amountLimit;\n emit FaucetLimit(amountLimit);\n }\n\n /// @notice return the maximum IERC20 token amount for an address.\n function getLimit() public view returns (uint256) {\n return _amountLimit;\n }\n\n /// @notice return the current IERC20 token balance for the contract.\n function balance() public view returns (uint256) {\n return _ierc20.balanceOf(address(this));\n }\n\n /// @notice retrieve all IERC20 token from contract to an address.\n /// @param receiver The address that will receive all IERC20 tokens.\n function retrieve(address receiver) public onlyOwner {\n uint256 accountBalance = balance();\n _ierc20.transferFrom(address(this), receiver, accountBalance);\n\n emit FaucetRetrieved(receiver, accountBalance);\n }\n\n /// @notice send amount of IERC20 to a receiver.\n /// @param amount The value of the IERC20 token that the receiver will received.\n function send(uint256 amount) public {\n require(\n amount <= _amountLimit,\n string(abi.encodePacked(\"Demand must not exceed \", Strings.toString(_amountLimit)))\n );\n\n uint256 accountBalance = balance();\n\n require(\n accountBalance > 0,\n string(abi.encodePacked(\"Insufficient balance on Faucet account: \", Strings.toString(accountBalance)))\n );\n require(\n _lastTimestamps[msg.sender] + _period < block.timestamp,\n string(abi.encodePacked(\"After each call you must wait \", Strings.toString(_period), \" seconds.\"))\n );\n _lastTimestamps[msg.sender] = block.timestamp;\n\n if (accountBalance < amount) {\n amount = accountBalance;\n }\n _ierc20.transferFrom(address(this), msg.sender, amount);\n\n emit FaucetSent(msg.sender, amount);\n }\n}\n" + }, + "src/solc_0.8/faucet/Faucets.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\n\ncontract Faucets is Ownable {\n event Faucet(address faucet, bool enabled);\n event Period(address faucet, uint256 period);\n event Limit(address faucet, uint256 limit);\n event Claimed(address faucet, address receiver, uint256 amount);\n event Withdrawn(address faucet, address receiver, uint256 amount);\n\n mapping(address => bool) private _faucets;\n mapping(address => uint256) private _periods;\n mapping(address => uint256) private _limits;\n mapping(address => mapping(address => uint256)) private _lastTimestamps;\n\n modifier exists(address faucet) {\n require(_faucets[faucet], \"Faucets: FAUCET_DOES_NOT_EXIST\");\n _;\n }\n\n function addFaucet(\n address faucet,\n uint256 period,\n uint256 limit\n ) public onlyOwner {\n require(!_faucets[faucet], \"Faucets: FAUCET_ALREADY_EXISTS\");\n _setFaucet(faucet);\n _setPeriod(faucet, period);\n _setLimit(faucet, limit);\n }\n\n function _setFaucet(address faucet) internal {\n _faucets[faucet] = true;\n emit Faucet(faucet, true);\n }\n\n function removeFaucet(address faucet) external onlyOwner exists(faucet) {\n _withdraw(faucet, _msgSender());\n delete _faucets[faucet];\n delete _periods[faucet];\n delete _limits[faucet];\n emit Faucet(faucet, false);\n }\n\n function getFaucet(address faucet) public view returns (bool) {\n return _faucets[faucet];\n }\n\n function setPeriod(address faucet, uint256 period) public onlyOwner exists(faucet) {\n _setPeriod(faucet, period);\n }\n\n function _setPeriod(address faucet, uint256 period) internal {\n _periods[faucet] = period;\n emit Period(faucet, period);\n }\n\n function getPeriod(address faucet) public view exists(faucet) returns (uint256) {\n return _periods[faucet];\n }\n\n function setLimit(address faucet, uint256 limit) public onlyOwner exists(faucet) {\n _setLimit(faucet, limit);\n }\n\n function _setLimit(address faucet, uint256 limit) internal {\n _limits[faucet] = limit;\n emit Limit(faucet, limit);\n }\n\n function getLimit(address faucet) public view exists(faucet) returns (uint256) {\n return _limits[faucet];\n }\n\n function getBalance(address faucet) public view exists(faucet) returns (uint256) {\n return IERC20(faucet).balanceOf(address(this));\n }\n\n function _getBalance(address faucet) internal view exists(faucet) returns (uint256) {\n return IERC20(faucet).balanceOf(address(this));\n }\n\n function canClaim(address faucet, address walletAddress) external view exists(faucet) returns (bool) {\n return _canClaim(faucet, walletAddress);\n }\n\n function _canClaim(address faucet, address walletAddress) internal view returns (bool) {\n return _lastTimestamps[faucet][walletAddress] + _periods[faucet] < block.timestamp;\n }\n\n function withdraw(address faucet, address receiver) external onlyOwner exists(faucet) {\n _withdraw(faucet, receiver);\n }\n\n function _withdraw(address faucet, address receiver) internal onlyOwner {\n uint256 accountBalance = _getBalance(faucet);\n IERC20(faucet).transfer(receiver, accountBalance);\n emit Withdrawn(faucet, receiver, accountBalance);\n }\n\n function claimBatch(address[] calldata faucets, uint256[] calldata amounts) public {\n require(faucets.length == amounts.length, \"Faucets: ARRAY_LENGTH_MISMATCH\");\n for (uint256 i = 0; i < faucets.length; i++) {\n claim(faucets[i], amounts[i]);\n }\n }\n\n function claim(address faucet, uint256 amount) public exists(faucet) {\n require(amount <= _limits[faucet], \"Faucets: AMOUNT_EXCEEDED_LIMIT\");\n uint256 accountBalance = _getBalance(faucet);\n require(accountBalance >= amount, \"Faucets: FAUCET_INSUFFICIENT_BALANCE\");\n require(_canClaim(faucet, msg.sender), \"Faucets: FAUCET_PERIOD_COOLDOWN\");\n _lastTimestamps[faucet][msg.sender] = block.timestamp;\n IERC20(faucet).transfer(msg.sender, amount);\n emit Claimed(faucet, msg.sender, amount);\n }\n}\n" + }, + "src/solc_0.8/OperatorFilterer/contracts/OperatorFilterRegistrant.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\nimport {IOperatorFilterRegistry} from \"../interfaces/IOperatorFilterRegistry.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\n/// @title OperatorFilterSubription\n/// @notice This contract is ment to register and copy the default subscription of the openSea for the operator filter and our Token contract are supposed to subscribe to This contract on openSea operator filter registry\n/// @custom:experimental This is an experimental contract. There could be future changes according to the change in the requirements\ncontract OperatorFilterSubscription is OwnableUpgradeable {\n address public constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);\n\n IOperatorFilterRegistry public constant operatorFilterRegistry =\n IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);\n\n function initialize() external initializer {\n // Subscribe and copy the entries of the Default subscription list of open sea.\n if (address(operatorFilterRegistry).code.length > 0) {\n operatorFilterRegistry.registerAndCopyEntries(address(this), DEFAULT_SUBSCRIPTION);\n }\n __Ownable_init();\n }\n}\n" + }, + "src/solc_0.8/OperatorFilterer/contracts/upgradeable/DefaultOperatorFiltererUpgradeable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {OperatorFiltererUpgradeable} from \"./OperatorFiltererUpgradeable.sol\";\n\n/// @title DefaultOperatorFiltererUpgradeable\n/// @notice This contract is ment to be imported in Token contracts to subscribe to the default Black list of Opensea.\nabstract contract DefaultOperatorFiltererUpgradeable is OperatorFiltererUpgradeable {\n // Registration address of the default subscription list.\n address public constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);\n\n function __DefaultOperatorFilterer_init(bool subscribe) internal onlyInitializing {\n __OperatorFilterer_init(DEFAULT_SUBSCRIPTION, subscribe);\n }\n}\n" + }, + "src/solc_0.8/OperatorFilterer/contracts/upgradeable/OperatorFiltererUpgradeable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {IOperatorFilterRegistry} from \"../../interfaces/IOperatorFilterRegistry.sol\";\nimport {ContextUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\n\n///@title OperatorFiltererUpgradeable\n///@author The Sandbox\n///@notice This contract would subscibe or copy or just to the subscription provided or just register to default subscription list\n///@dev This contract is the upgradeable version of the OpenSea implementation https://github.com/ProjectOpenSea/operator-filter-registry/blob/main/src/OperatorFilterer.sol and adapted to the 0.5.9 solidity version\nabstract contract OperatorFiltererUpgradeable is ContextUpgradeable {\n IOperatorFilterRegistry public operatorFilterRegistry;\n\n event ContractRegistered(address indexed subscriptionOrRegistrant, bool subscribe);\n\n function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal onlyInitializing {\n _register(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n /**\n * @notice Register this contract into the registry\n * @param subscriptionOrRegistrantToCopy address to subscribe or copy entries from\n * @param subscribe should it subscribe\n */\n function _register(address subscriptionOrRegistrantToCopy, bool subscribe) internal {\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isRegistered(address(this))) {\n if (subscribe) {\n operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);\n } else {\n if (subscriptionOrRegistrantToCopy != address(0)) {\n operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);\n } else {\n operatorFilterRegistry.register(address(this));\n }\n }\n }\n }\n emit ContractRegistered(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n modifier onlyAllowedOperator(address from) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n // Allow spending tokens from addresses with balance\n // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred\n // from an EOA.\n if (from == _msgSender()) {\n _;\n return;\n }\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), _msgSender())) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n\n modifier onlyAllowedOperatorApproval(address operator) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), operator)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n}\n" + }, + "src/solc_0.8/OperatorFilterer/interfaces/IOperatorFilterRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\n/**\n * @title IOperatorFilterRegistry\n * @author OpenSea\n * @notice Interface of the operator filter registry\n * @dev This interface comes from OpenSea https://github.com/ProjectOpenSea/operator-filter-registry/blob/main/src/IOperatorFilterRegistry.sol and adapted to the 0.5.9 solidity version\n */\ninterface IOperatorFilterRegistry {\n /**\n * @notice Check if the operator is allowed for the given registrant\n * @param registrant address of the registrant\n * @param operator operator address to check\n * @return is the operator allowed\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool);\n\n /**\n * @notice Register a new address\n * @param registrant address to register\n */\n function register(address registrant) external;\n\n /**\n * @notice Register a new address & subscribe to an address\n * @param registrant address of the registrant\n * @param subscription address where the registrant is subscribed to\n */\n function registerAndSubscribe(address registrant, address subscription) external;\n\n /**\n * @notice Register and copy entries of another registrant\n * @param registrant address of the registrant\n * @param registrantToCopy address to copy from\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n\n /**\n * @notice update the operator for a registrant\n * @param registrant address of the registrant\n * @param operator operator to be updated\n * @param filtered is it filtered\n */\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external;\n\n /**\n * @notice Update operators for a registrant\n * @param registrant address of the registrant\n * @param operators addresses of the operators\n * @param filtered is it filtered\n */\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external;\n\n /**\n * @notice Update code hash\n * @param registrant address of the registrant\n * @param codehash code hash\n * @param filtered is it filtered\n */\n function updateCodeHash(\n address registrant,\n bytes32 codehash,\n bool filtered\n ) external;\n\n /**\n * @notice Update code hashes\n * @param registrant address of the registrant\n * @param codeHashes code hashes\n * @param filtered is it filtered\n */\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external;\n\n /**\n * @notice Subscribe a registrant\n * @param registrant address of the registrant\n * @param registrantToSubscribe address to subscribe with\n */\n function subscribe(address registrant, address registrantToSubscribe) external;\n\n /**\n * @notice Unsubscribe a registrant\n * @param registrant address of the registrant\n * @param copyExistingEntries copy existing entries\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n\n /**\n * @notice Get the subscription of an address\n * @param addr address to check\n * @return registrant the registrant address\n */\n function subscriptionOf(address addr) external returns (address registrant);\n\n /**\n * @notice Get the subscribers of the registrant\n * @param registrant address of the registrant\n * @return the subscribers addresses\n */\n function subscribers(address registrant) external returns (address[] memory);\n\n /**\n * @notice Get a specific subscriber\n * @param registrant address of the registrant\n * @param index index to check\n * @return the ith subscriber of the registrant\n */\n function subscriberAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Copy the entries of a registrant\n * @param registrant address of the registrant\n * @param registrantToCopy address to copy\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Is a registrant filtered\n * @param registrant address of the registrant\n * @param operator operator address to check\n * @return is it filtered\n */\n function isOperatorFiltered(address registrant, address operator) external returns (bool);\n\n /**\n * @notice Is the code hash of an operator filtered\n * @param registrant address of the registrant\n * @param operatorWithCode operator address to check\n * @return is it filtered\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);\n\n /**\n * @notice Is the code hash filtered\n * @param registrant address of the registrant\n * @param codeHash code hash\n * @return is it filtered\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);\n\n /**\n * @notice Get the filtered operators\n * @param addr address to check\n * @return filtered operators\n */\n function filteredOperators(address addr) external returns (address[] memory);\n\n /**\n * @notice Get the filtered code hashes\n * @param addr address to check\n * @return filtered code hashes\n */\n function filteredCodeHashes(address addr) external returns (bytes32[] memory);\n\n /**\n * @notice Get a specific operator\n * @param registrant address of the registrant\n * @param index index to check\n * @return address of the operator\n */\n function filteredOperatorAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Get the ith filtered code hash\n * @param registrant address of the registrant\n * @param index index to check\n * @return the code hash\n */\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);\n\n /**\n * @notice Is the address registered\n * @param addr address to check\n * @return is it registered\n */\n function isRegistered(address addr) external returns (bool);\n\n /**\n * @notice Get the code hash for this address\n * @param addr address to check\n * @return the code hash\n */\n function codeHashOf(address addr) external returns (bytes32);\n}\n" + }, + "src/solc_0.8/permit/Permit.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"../common/interfaces/IERC20Extended.sol\";\nimport \"../common/BaseWithStorage/WithPermit.sol\";\n\n/// @title Permit contract\n/// @notice This contract manages approvals of SAND via signature\ncontract Permit is WithPermit {\n IERC20Extended internal immutable _sand;\n\n constructor(IERC20Extended sandContractAddress) {\n _sand = sandContractAddress;\n }\n\n /// @notice Permit the expenditure of SAND by a nominated spender.\n /// @param owner The owner of the ERC20 tokens.\n /// @param spender The nominated spender of the ERC20 tokens.\n /// @param value The value (allowance) of the ERC20 tokens that the nominated.\n /// spender will be allowed to spend.\n /// @param deadline The deadline for granting permission to the spender.\n /// @param v The final 1 byte of signature.\n /// @param r The first 32 bytes of signature.\n /// @param s The second 32 bytes of signature.\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public override {\n checkApproveFor(owner, spender, value, deadline, v, r, s);\n _sand.approveFor(owner, spender, value);\n }\n}\n" + }, + "src/solc_0.8/polygon/child/land/PolygonLandBaseToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable code-complexity\n\npragma solidity 0.8.2;\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\";\nimport \"../../../common/BaseWithStorage/ERC721BaseTokenV2.sol\";\nimport \"../../../common/interfaces/IPolygonLand.sol\";\n\nabstract contract PolygonLandBaseToken is IPolygonLand, Initializable, ERC721BaseTokenV2 {\n using AddressUpgradeable for address;\n\n uint256 internal constant GRID_SIZE = 408;\n\n uint256 internal constant LAYER = 0xFF00000000000000000000000000000000000000000000000000000000000000;\n uint256 internal constant LAYER_1x1 = 0x0000000000000000000000000000000000000000000000000000000000000000;\n uint256 internal constant LAYER_3x3 = 0x0100000000000000000000000000000000000000000000000000000000000000;\n uint256 internal constant LAYER_6x6 = 0x0200000000000000000000000000000000000000000000000000000000000000;\n uint256 internal constant LAYER_12x12 = 0x0300000000000000000000000000000000000000000000000000000000000000;\n uint256 internal constant LAYER_24x24 = 0x0400000000000000000000000000000000000000000000000000000000000000;\n\n mapping(address => bool) internal _minters;\n\n event Minter(address minter, bool enabled);\n\n modifier validQuad(\n uint256 size,\n uint256 x,\n uint256 y\n ) {\n require(size == 1 || size == 3 || size == 6 || size == 12 || size == 24, \"Invalid size\");\n require(x % size == 0 && y % size == 0, \"Invalid coordinates\");\n require(x <= GRID_SIZE - size && y <= GRID_SIZE - size, \"Out of bounds\");\n\n _;\n }\n\n /**\n * @notice Return the name of the token contract\n * @return The name of the token contract\n */\n function name() public pure returns (string memory) {\n return \"Sandbox's LANDs\";\n }\n\n /**\n * @notice Return the symbol of the token contract\n * @return The symbol of the token contract\n */\n function symbol() public pure returns (string memory) {\n return \"LAND\";\n }\n\n /// @notice total width of the map\n /// @return width\n function width() public pure returns (uint256) {\n return GRID_SIZE;\n }\n\n /// @notice total height of the map\n /// @return height\n function height() public pure returns (uint256) {\n return GRID_SIZE;\n }\n\n /// @notice x coordinate of Land token\n /// @param id tokenId\n /// @return the x coordinates\n function getX(uint256 id) external view returns (uint256) {\n require(_ownerOf(id) != address(0), \"token does not exist\");\n return id % GRID_SIZE;\n }\n\n /// @notice y coordinate of Land token\n /// @param id tokenId\n /// @return the y coordinates\n function getY(uint256 id) external view returns (uint256) {\n require(_ownerOf(id) != address(0), \"token does not exist\");\n return id / GRID_SIZE;\n }\n\n /**\n * @notice Return the URI of a specific token\n * @param id The id of the token\n * @return The URI of the token\n */\n function tokenURI(uint256 id) public view returns (string memory) {\n require(_ownerOf(id) != address(0), \"Id does not exist\");\n return\n string(\n abi.encodePacked(\"https://api.sandbox.game/lands/\", StringsUpgradeable.toString(id), \"/metadata.json\")\n );\n }\n\n /**\n * @notice Check if the contract supports an interface\n * 0x01ffc9a7 is ERC-165\n * 0x80ac58cd is ERC-721\n * 0x5b5e139f is ERC-721 metadata\n * @param id The id of the interface\n * @return True if the interface is supported\n */\n function supportsInterface(bytes4 id) public pure override returns (bool) {\n return id == 0x01ffc9a7 || id == 0x80ac58cd || id == 0x5b5e139f;\n }\n\n /**\n * @notice Mint a new quad (aligned to a quad tree with size 1, 3, 6, 12 or 24 only)\n * @param user The recipient of the new quad\n * @param size The size of the new quad\n * @param x The top left x coordinate of the new quad\n * @param y The top left y coordinate of the new quad\n * @param data extra data to pass to the transfer\n */\n function mintQuad(\n address user,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes memory data\n ) external virtual override {\n require(isMinter(_msgSender()), \"!AUTHORIZED\");\n _mintQuad(user, size, x, y, data);\n }\n\n function _mintQuad(\n address to,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes memory data\n ) internal {\n require(to != address(0), \"to is zero address\");\n require(!exists(size, x, y), \"Already minted\");\n\n uint256 quadId;\n uint256 id = x + y * GRID_SIZE;\n\n if (size == 1) {\n quadId = id;\n } else if (size == 3) {\n quadId = LAYER_3x3 + id;\n } else if (size == 6) {\n quadId = LAYER_6x6 + id;\n } else if (size == 12) {\n quadId = LAYER_12x12 + id;\n } else if (size == 24) {\n quadId = LAYER_24x24 + id;\n }\n\n for (uint256 i = 0; i < size * size; i++) {\n emit Transfer(address(0), to, _idInPath(i, size, x, y));\n }\n\n _owners[quadId] = uint256(uint160(address(to)));\n _numNFTPerAddress[to] += size * size;\n\n _checkBatchReceiverAcceptQuad(_msgSender(), address(0), to, size, x, y, data);\n }\n\n function batchTransferQuad(\n address from,\n address to,\n uint256[] calldata sizes,\n uint256[] calldata xs,\n uint256[] calldata ys,\n bytes calldata data\n ) external override {\n require(from != address(0), \"from is zero address\");\n require(to != address(0), \"can't send to zero address\");\n require(sizes.length == xs.length && xs.length == ys.length, \"invalid data\");\n if (_msgSender() != from) {\n require(\n _operatorsForAll[from][_msgSender()] || _superOperators[_msgSender()],\n \"not authorized to transferMultiQuads\"\n );\n }\n uint256 numTokensTransfered = 0;\n for (uint256 i = 0; i < sizes.length; i++) {\n uint256 size = sizes[i];\n _transferQuad(from, to, size, xs[i], ys[i]);\n numTokensTransfered += size * size;\n }\n _numNFTPerAddress[from] -= numTokensTransfered;\n _numNFTPerAddress[to] += numTokensTransfered;\n\n if (to.isContract() && _checkInterfaceWith10000Gas(to, ERC721_MANDATORY_RECEIVER)) {\n uint256[] memory ids = new uint256[](numTokensTransfered);\n uint256 counter = 0;\n for (uint256 j = 0; j < sizes.length; j++) {\n uint256 size = sizes[j];\n for (uint256 i = 0; i < size * size; i++) {\n ids[counter] = _idInPath(i, size, xs[j], ys[j]);\n counter++;\n }\n }\n require(\n _checkOnERC721BatchReceived(_msgSender(), from, to, ids, data),\n \"erc721 batch transfer rejected by to\"\n );\n }\n }\n\n function transferQuad(\n address from,\n address to,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes calldata data\n ) external override {\n require(from != address(0), \"from is zero address\");\n require(to != address(0), \"can't send to zero address\");\n if (_msgSender() != from) {\n require(\n _operatorsForAll[from][_msgSender()] || _superOperators[_msgSender()],\n \"not authorized to transferQuad\"\n );\n }\n _transferQuad(from, to, size, x, y);\n _numNFTPerAddress[from] -= size * size;\n _numNFTPerAddress[to] += size * size;\n\n _checkBatchReceiverAcceptQuad(_msgSender(), from, to, size, x, y, data);\n }\n\n function batchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n bytes calldata data\n ) public override(ILandToken, ERC721BaseTokenV2) {\n super.batchTransferFrom(from, to, ids, data);\n }\n\n function exists(\n uint256 size,\n uint256 x,\n uint256 y\n ) public view override validQuad(size, x, y) returns (bool) {\n if (_owners[LAYER_24x24 + (x / 24) * 24 + ((y / 24) * 24) * GRID_SIZE] != 0) return true;\n uint256 toX = x + size;\n uint256 toY = y + size;\n if (size <= 12) {\n if (_owners[LAYER_12x12 + (x / 12) * 12 + ((y / 12) * 12) * GRID_SIZE] != 0) return true;\n } else {\n for (uint256 x12i = x; x12i < toX; x12i += 12) {\n for (uint256 y12i = y; y12i < toY; y12i += 12) {\n uint256 id12x12 = LAYER_12x12 + x12i + y12i * GRID_SIZE;\n if (_owners[id12x12] != 0) return true;\n }\n }\n }\n\n if (size <= 6) {\n if (_owners[LAYER_6x6 + (x / 6) * 6 + ((y / 6) * 6) * GRID_SIZE] != 0) return true;\n } else {\n for (uint256 x6i = x; x6i < toX; x6i += 6) {\n for (uint256 y6i = y; y6i < toY; y6i += 6) {\n uint256 id6x6 = LAYER_6x6 + x6i + y6i * GRID_SIZE;\n if (_owners[id6x6] != 0) return true;\n }\n }\n }\n\n if (size <= 3) {\n if (_owners[LAYER_3x3 + (x / 3) * 3 + ((y / 3) * 3) * GRID_SIZE] != 0) return true;\n } else {\n for (uint256 x3i = x; x3i < toX; x3i += 3) {\n for (uint256 y3i = y; y3i < toY; y3i += 3) {\n uint256 id3x3 = LAYER_3x3 + x3i + y3i * GRID_SIZE;\n if (_owners[id3x3] != 0) return true;\n }\n }\n }\n\n for (uint256 i = 0; i < size * size; i++) {\n if (_owners[_idInPath(i, size, x, y)] != 0) return true;\n }\n\n return false;\n }\n\n /// @notice Enable or disable the ability of `minter` to transfer tokens of all (minter rights).\n /// @param minter address that will be given/removed minter right.\n /// @param enabled set whether the minter is enabled or disabled.\n function setMinter(address minter, bool enabled) external {\n require(_msgSender() == _admin, \"only admin is allowed to add minters\");\n require(minter != address(0), \"PolygonLand: Invalid address\");\n _minters[minter] = enabled;\n emit Minter(minter, enabled);\n }\n\n /// @notice check whether address `who` is given minter rights.\n /// @param who The address to query.\n /// @return whether the address has minter rights.\n function isMinter(address who) public view returns (bool) {\n return _minters[who];\n }\n\n function _transferQuad(\n address from,\n address to,\n uint256 size,\n uint256 x,\n uint256 y\n ) internal validQuad(size, x, y) {\n if (size == 1) {\n uint256 id1x1 = x + y * GRID_SIZE;\n address owner = _ownerOf(id1x1);\n require(owner != address(0), \"token does not exist\");\n require(owner == from, \"not owner in _transferQuad\");\n _owners[id1x1] = uint256(uint160(address(to)));\n } else {\n _regroup(from, to, size, x, y);\n }\n for (uint256 i = 0; i < size * size; i++) {\n emit Transfer(from, to, _idInPath(i, size, x, y));\n }\n }\n\n function _idInPath(\n uint256 i,\n uint256 size,\n uint256 x,\n uint256 y\n ) internal pure returns (uint256) {\n uint256 row = i / size;\n if (row % 2 == 0) {\n // allow ids to follow a path in a quad\n return (x + (i % size)) + ((y + row) * GRID_SIZE);\n } else {\n return ((x + size) - (1 + (i % size))) + ((y + row) * GRID_SIZE);\n }\n }\n\n function _regroup(\n address from,\n address to,\n uint256 size,\n uint256 x,\n uint256 y\n ) internal {\n if (size == 3) {\n _regroup3x3(from, to, x, y, true);\n } else if (size == 6) {\n _regroup6x6(from, to, x, y, true);\n } else if (size == 12) {\n _regroup12x12(from, to, x, y, true);\n } else if (size == 24) {\n _regroup24x24(from, to, x, y, true);\n }\n }\n\n function _regroup3x3(\n address from,\n address to,\n uint256 x,\n uint256 y,\n bool set\n ) internal returns (bool) {\n uint256 id = x + y * GRID_SIZE;\n uint256 quadId = LAYER_3x3 + id;\n bool ownerOfAll = true;\n for (uint256 xi = x; xi < x + 3; xi++) {\n for (uint256 yi = y; yi < y + 3; yi++) {\n ownerOfAll = _checkAndClear(from, xi + yi * GRID_SIZE) && ownerOfAll;\n }\n }\n if (set) {\n if (!ownerOfAll) {\n require(_ownerOfQuad(3, x, y) == from, \"not owner of all sub quads nor parent quads\");\n }\n _owners[quadId] = uint256(uint160(address(to)));\n return true;\n }\n return ownerOfAll;\n }\n\n function _regroup6x6(\n address from,\n address to,\n uint256 x,\n uint256 y,\n bool set\n ) internal returns (bool) {\n uint256 id = x + y * GRID_SIZE;\n uint256 quadId = LAYER_6x6 + id;\n bool ownerOfAll = true;\n for (uint256 xi = x; xi < x + 6; xi += 3) {\n for (uint256 yi = y; yi < y + 6; yi += 3) {\n bool ownAllIndividual = _regroup3x3(from, to, xi, yi, false);\n uint256 id3x3 = LAYER_3x3 + xi + yi * GRID_SIZE;\n uint256 owner3x3 = _owners[id3x3];\n if (owner3x3 != 0) {\n if (!ownAllIndividual) {\n require(owner3x3 == uint256(uint160(address(from))), \"not owner of 3x3 quad\");\n }\n _owners[id3x3] = 0;\n }\n ownerOfAll = (ownAllIndividual || owner3x3 != 0) && ownerOfAll;\n }\n }\n if (set) {\n if (!ownerOfAll) {\n require(_ownerOfQuad(6, x, y) == from, \"not owner of all sub quads nor parent quads\");\n }\n _owners[quadId] = uint256(uint160(address(to)));\n return true;\n }\n return ownerOfAll;\n }\n\n function _regroup12x12(\n address from,\n address to,\n uint256 x,\n uint256 y,\n bool set\n ) internal returns (bool) {\n uint256 id = x + y * GRID_SIZE;\n uint256 quadId = LAYER_12x12 + id;\n bool ownerOfAll = true;\n for (uint256 xi = x; xi < x + 12; xi += 6) {\n for (uint256 yi = y; yi < y + 12; yi += 6) {\n bool ownAllIndividual = _regroup6x6(from, to, xi, yi, false);\n uint256 id6x6 = LAYER_6x6 + xi + yi * GRID_SIZE;\n uint256 owner6x6 = _owners[id6x6];\n if (owner6x6 != 0) {\n if (!ownAllIndividual) {\n require(owner6x6 == uint256(uint160(address(from))), \"not owner of 6x6 quad\");\n }\n _owners[id6x6] = 0;\n }\n ownerOfAll = (ownAllIndividual || owner6x6 != 0) && ownerOfAll;\n }\n }\n if (set) {\n if (!ownerOfAll) {\n require(_ownerOfQuad(12, x, y) == from, \"not owner of all sub quads nor parent quads\");\n }\n _owners[quadId] = uint256(uint160(address(to)));\n return true;\n }\n return ownerOfAll;\n }\n\n function _regroup24x24(\n address from,\n address to,\n uint256 x,\n uint256 y,\n bool set\n ) internal returns (bool) {\n uint256 id = x + y * GRID_SIZE;\n uint256 quadId = LAYER_24x24 + id;\n bool ownerOfAll = true;\n for (uint256 xi = x; xi < x + 24; xi += 12) {\n for (uint256 yi = y; yi < y + 24; yi += 12) {\n bool ownAllIndividual = _regroup12x12(from, to, xi, yi, false);\n uint256 id12x12 = LAYER_12x12 + xi + yi * GRID_SIZE;\n uint256 owner12x12 = _owners[id12x12];\n if (owner12x12 != 0) {\n if (!ownAllIndividual) {\n require(owner12x12 == uint256(uint160(address(from))), \"not owner of 12x12 quad\");\n }\n _owners[id12x12] = 0;\n }\n ownerOfAll = (ownAllIndividual || owner12x12 != 0) && ownerOfAll;\n }\n }\n if (set) {\n if (!ownerOfAll) {\n require(\n _owners[quadId] == uint256(uint160(address(from))),\n \"not owner of all sub quads not parent quad\"\n );\n }\n _owners[quadId] = uint256(uint160(address(to)));\n return true;\n }\n return ownerOfAll || _owners[quadId] == uint256(uint160(address(from)));\n }\n\n function _ownerOfQuad(\n uint256 size,\n uint256 x,\n uint256 y\n ) internal returns (address) {\n uint256 layer;\n uint256 parentSize = size * 2;\n if (size == 3) {\n layer = LAYER_3x3;\n } else if (size == 6) {\n layer = LAYER_6x6;\n } else if (size == 12) {\n layer = LAYER_12x12;\n } else if (size == 24) {\n layer = LAYER_24x24;\n } else {\n require(false, \"Invalid size\");\n }\n\n address owner = address(uint160(_owners[layer + (x / size) * size + ((y / size) * size) * GRID_SIZE]));\n if (owner != address(0)) {\n return owner;\n } else if (size < 24) {\n return _ownerOfQuad(parentSize, x, y);\n }\n return address(0);\n }\n\n function _ownerOf(uint256 id) internal view override returns (address) {\n require(id & LAYER == 0, \"Invalid token id\");\n uint256 x = id % GRID_SIZE;\n uint256 y = id / GRID_SIZE;\n uint256 owner1x1 = _owners[id];\n\n if ((owner1x1 & BURNED_FLAG) == BURNED_FLAG) {\n return address(0);\n }\n\n if (owner1x1 != 0) {\n return address(uint160(owner1x1)); //we check if the quad exists as an 1x1 quad, then 3x3, and so on..\n } else {\n address owner3x3 = address(uint160(_owners[LAYER_3x3 + (x / 3) * 3 + ((y / 3) * 3) * GRID_SIZE]));\n if (owner3x3 != address(0)) {\n return owner3x3;\n } else {\n address owner6x6 = address(uint160(_owners[LAYER_6x6 + (x / 6) * 6 + ((y / 6) * 6) * GRID_SIZE]));\n if (owner6x6 != address(0)) {\n return owner6x6;\n } else {\n address owner12x12 =\n address(uint160(_owners[LAYER_12x12 + (x / 12) * 12 + ((y / 12) * 12) * GRID_SIZE]));\n if (owner12x12 != address(0)) {\n return owner12x12;\n } else {\n return address(uint160(_owners[LAYER_24x24 + (x / 24) * 24 + ((y / 24) * 24) * GRID_SIZE]));\n }\n }\n }\n }\n }\n\n function _checkAndClear(address from, uint256 id) internal returns (bool) {\n uint256 owner = _owners[id];\n if (owner != 0) {\n require((owner & BURNED_FLAG) != BURNED_FLAG, \"not owner\");\n require(address(uint160(owner)) == from, \"not owner\");\n _owners[id] = 0;\n return true;\n }\n return false;\n }\n\n function _checkBatchReceiverAcceptQuad(\n address operator,\n address from,\n address to,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes memory data\n ) internal {\n if (to.isContract() && _checkInterfaceWith10000Gas(to, ERC721_MANDATORY_RECEIVER)) {\n uint256[] memory ids = new uint256[](size * size);\n for (uint256 i = 0; i < size * size; i++) {\n ids[i] = _idInPath(i, size, x, y);\n }\n require(_checkOnERC721BatchReceived(operator, from, to, ids, data), \"erc721 batch transfer rejected by to\");\n }\n }\n\n function _ownerAndOperatorEnabledOf(uint256 id)\n internal\n view\n override\n returns (address owner, bool operatorEnabled)\n {\n require(id & LAYER == 0, \"Invalid token id\");\n uint256 x = id % GRID_SIZE;\n uint256 y = id / GRID_SIZE;\n uint256 owner1x1 = _owners[id];\n\n if ((owner1x1 & BURNED_FLAG) == BURNED_FLAG) {\n owner = address(0);\n operatorEnabled = (owner1x1 & OPERATOR_FLAG) == OPERATOR_FLAG;\n return (owner, operatorEnabled);\n }\n\n if (owner1x1 != 0) {\n owner = address(uint160(owner1x1));\n operatorEnabled = (owner1x1 & OPERATOR_FLAG) == OPERATOR_FLAG;\n } else {\n address owner3x3 = address(uint160(_owners[LAYER_3x3 + (x / 3) * 3 + ((y / 3) * 3) * GRID_SIZE]));\n if (owner3x3 != address(uint160(0))) {\n owner = owner3x3;\n operatorEnabled = false;\n } else {\n address owner6x6 = address(uint160(_owners[LAYER_6x6 + (x / 6) * 6 + ((y / 6) * 6) * GRID_SIZE]));\n if (owner6x6 != address(uint160(0))) {\n owner = owner6x6;\n operatorEnabled = false;\n } else {\n address owner12x12 =\n address(uint160(_owners[LAYER_12x12 + (x / 12) * 12 + ((y / 12) * 12) * GRID_SIZE]));\n if (owner12x12 != address(uint160(0))) {\n owner = owner12x12;\n operatorEnabled = false;\n } else {\n owner = address(uint160(_owners[LAYER_24x24 + (x / 24) * 24 + ((y / 24) * 24) * GRID_SIZE]));\n operatorEnabled = false;\n }\n }\n }\n }\n }\n\n // Empty storage space in contracts for future enhancements\n // ref: https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/issues/13)\n uint256[49] private __gap;\n}\n" + }, + "src/solc_0.8/polygon/child/land/PolygonLandBaseTokenV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable code-complexity\n\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\";\nimport \"../../../common/BaseWithStorage/ERC721BaseTokenV2.sol\";\nimport \"../../../common/interfaces/IPolygonLand.sol\";\n\n/**\n * @title PolygonLandBaseTokenV2\n * @author The Sandbox\n * @notice Implement LAND and quad functionalities on top of an ERC721 token\n * @dev This contract implements a quad tree structure to handle groups of ERC721 tokens at once\n */\nabstract contract PolygonLandBaseTokenV2 is IPolygonLand, Initializable, ERC721BaseTokenV2 {\n using AddressUpgradeable for address;\n\n uint256 internal constant GRID_SIZE = 408;\n\n uint256 internal constant LAYER = 0xFF00000000000000000000000000000000000000000000000000000000000000;\n uint256 internal constant LAYER_1x1 = 0x0000000000000000000000000000000000000000000000000000000000000000;\n uint256 internal constant LAYER_3x3 = 0x0100000000000000000000000000000000000000000000000000000000000000;\n uint256 internal constant LAYER_6x6 = 0x0200000000000000000000000000000000000000000000000000000000000000;\n uint256 internal constant LAYER_12x12 = 0x0300000000000000000000000000000000000000000000000000000000000000;\n uint256 internal constant LAYER_24x24 = 0x0400000000000000000000000000000000000000000000000000000000000000;\n\n mapping(address => bool) internal _minters;\n\n event Minter(address indexed minter, bool enabled);\n\n struct Land {\n uint256 x;\n uint256 y;\n uint256 size;\n }\n\n /// @notice transfer multiple quad (aligned to a quad tree with size 3, 6, 12 or 24 only)\n /// @param from current owner of the quad\n /// @param to destination\n /// @param sizes list of sizes for each quad\n /// @param xs list of bottom left x coordinates for each quad\n /// @param ys list of bottom left y coordinates for each quad\n /// @param data additional data\n function batchTransferQuad(\n address from,\n address to,\n uint256[] calldata sizes,\n uint256[] calldata xs,\n uint256[] calldata ys,\n bytes calldata data\n ) external override {\n require(from != address(0), \"from is zero address\");\n require(to != address(0), \"can't send to zero address\");\n require(sizes.length == xs.length, \"PolygonLandBaseTokenV2: sizes's and x's length are different\");\n require(xs.length == ys.length, \"PolygonLandBaseTokenV2: x's and y's length are different\");\n if (_msgSender() != from) {\n require(\n _operatorsForAll[from][_msgSender()] || _superOperators[_msgSender()],\n \"not authorized to transferMultiQuads\"\n );\n }\n uint256 numTokensTransfered = 0;\n for (uint256 i = 0; i < sizes.length; i++) {\n uint256 size = sizes[i];\n _transferQuad(from, to, size, xs[i], ys[i]);\n numTokensTransfered += size * size;\n }\n _numNFTPerAddress[from] -= numTokensTransfered;\n _numNFTPerAddress[to] += numTokensTransfered;\n\n if (to.isContract() && _checkInterfaceWith10000Gas(to, ERC721_MANDATORY_RECEIVER)) {\n uint256[] memory ids = new uint256[](numTokensTransfered);\n uint256 counter = 0;\n for (uint256 j = 0; j < sizes.length; j++) {\n uint256 size = sizes[j];\n for (uint256 i = 0; i < size * size; i++) {\n ids[counter] = _idInPath(i, size, xs[j], ys[j]);\n counter++;\n }\n }\n require(\n _checkOnERC721BatchReceived(_msgSender(), from, to, ids, data),\n \"erc721 batch transfer rejected by to\"\n );\n }\n }\n\n /// @notice Enable or disable the ability of `minter` to transfer tokens of all (minter rights).\n /// @param minter address that will be given/removed minter right.\n /// @param enabled set whether the minter is enabled or disabled.\n function setMinter(address minter, bool enabled) external onlyAdmin {\n require(minter != address(0), \"PolygonLand: Invalid address\");\n _minters[minter] = enabled;\n emit Minter(minter, enabled);\n }\n\n /// @notice transfer one quad (aligned to a quad tree with size 3, 6, 12 or 24 only)\n /// @param from current owner of the quad\n /// @param to destination\n /// @param size size of the quad\n /// @param x The top left x coordinate of the quad\n /// @param y The top left y coordinate of the quad\n /// @param data additional data for transfer\n function transferQuad(\n address from,\n address to,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes calldata data\n ) external override {\n require(from != address(0), \"from is zero address\");\n require(to != address(0), \"can't send to zero address\");\n if (_msgSender() != from) {\n require(\n _operatorsForAll[from][_msgSender()] || _superOperators[_msgSender()],\n \"not authorized to transferQuad\"\n );\n }\n _transferQuad(from, to, size, x, y);\n _numNFTPerAddress[from] -= size * size;\n _numNFTPerAddress[to] += size * size;\n\n _checkBatchReceiverAcceptQuad(_msgSender(), from, to, size, x, y, data);\n }\n\n /**\n * @notice Mint a new quad (aligned to a quad tree with size 1, 3, 6, 12 or 24 only)\n * @param user The recipient of the new quad\n * @param size The size of the new quad\n * @param x The top left x coordinate of the new quad\n * @param y The top left y coordinate of the new quad\n * @param data extra data to pass to the transfer\n */\n function mintQuad(\n address user,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes memory data\n ) external virtual override {\n _isValidQuad(size, x, y);\n require(isMinter(_msgSender()), \"!AUTHORIZED\");\n _mintQuad(user, size, x, y, data);\n }\n\n /**\n * @notice Checks if a parent quad has child quads already minted.\n * Then mints the rest child quads and transfers the parent quad.\n * Should only be called by the tunnel.\n * @param to The recipient of the new quad\n * @param size The size of the new quad\n * @param x The top left x coordinate of the new quad\n * @param y The top left y coordinate of the new quad\n * @param data extra data to pass to the transfer\n */\n function mintAndTransferQuad(\n address to,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes calldata data\n ) external virtual {\n require(isMinter(msg.sender), \"!AUTHORIZED\");\n require(to != address(0), \"to is zero address\");\n\n if (exists(size, x, y)) {\n _transferQuad(msg.sender, to, size, x, y);\n _numNFTPerAddress[msg.sender] -= size * size;\n _numNFTPerAddress[to] += size * size;\n _checkBatchReceiverAcceptQuad(msg.sender, msg.sender, to, size, x, y, data);\n } else {\n _mintAndTransferQuad(to, size, x, y, data);\n }\n }\n\n /// @notice x coordinate of Land token\n /// @param id tokenId\n /// @return the x coordinates\n function getX(uint256 id) external pure returns (uint256) {\n return _getX(id);\n }\n\n /// @inheritdoc ERC721BaseTokenV2\n function batchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n bytes calldata data\n ) public virtual override(ILandToken, ERC721BaseTokenV2) {\n super.batchTransferFrom(from, to, ids, data);\n }\n\n /// @notice y coordinate of Land token\n /// @param id tokenId\n /// @return the y coordinates\n function getY(uint256 id) external pure returns (uint256) {\n return _getY(id);\n }\n\n /**\n * @notice Check if the contract supports an interface\n * 0x01ffc9a7 is ERC-165\n * 0x80ac58cd is ERC-721\n * 0x5b5e139f is ERC-721 metadata\n * @param id The id of the interface\n * @return True if the interface is supported\n */\n function supportsInterface(bytes4 id) public pure override returns (bool) {\n return id == 0x01ffc9a7 || id == 0x80ac58cd || id == 0x5b5e139f;\n }\n\n /**\n * @notice Return the name of the token contract\n * @return The name of the token contract\n */\n function name() public pure returns (string memory) {\n return \"Sandbox's LANDs\";\n }\n\n /// @notice check whether address `who` is given minter rights.\n /// @param who The address to query.\n /// @return whether the address has minter rights.\n function isMinter(address who) public view returns (bool) {\n return _minters[who];\n }\n\n /// @notice checks if Land has been minted or not\n /// @param size size of the\n /// @param x x coordinate of the quad\n /// @param y y coordinate of the quad\n /// @return bool for if Land has been minted or not\n function exists(\n uint256 size,\n uint256 x,\n uint256 y\n ) public view override returns (bool) {\n _isValidQuad(size, x, y);\n return _ownerOfQuad(size, x, y) != address(0);\n }\n\n /**\n * @notice Return the symbol of the token contract\n * @return The symbol of the token contract\n */\n function symbol() public pure returns (string memory) {\n return \"LAND\";\n }\n\n /// @notice total width of the map\n /// @return width\n function width() public pure returns (uint256) {\n return GRID_SIZE;\n }\n\n /// @notice total height of the map\n /// @return height\n function height() public pure returns (uint256) {\n return GRID_SIZE;\n }\n\n /**\n * @notice Return the URI of a specific token\n * @param id The id of the token\n * @return The URI of the token\n */\n function tokenURI(uint256 id) public view returns (string memory) {\n require(_ownerOf(id) != address(0), \"Id does not exist\");\n return\n string(\n abi.encodePacked(\"https://api.sandbox.game/lands/\", StringsUpgradeable.toString(id), \"/metadata.json\")\n );\n }\n\n function _isValidQuad(\n uint256 size,\n uint256 x,\n uint256 y\n ) internal pure {\n require(size == 1 || size == 3 || size == 6 || size == 12 || size == 24, \"Invalid size\");\n require(x % size == 0, \"Invalid x coordinate\");\n require(y % size == 0, \"Invalid y coordinate\");\n require(x <= GRID_SIZE - size, \"x out of bounds\");\n require(y <= GRID_SIZE - size, \"y out of bounds\");\n }\n\n function _transferQuad(\n address from,\n address to,\n uint256 size,\n uint256 x,\n uint256 y\n ) internal {\n _isValidQuad(size, x, y);\n if (size == 1) {\n uint256 id1x1 = _getQuadId(LAYER_1x1, x, y);\n address owner = _ownerOf(id1x1);\n require(owner != address(0), \"token does not exist\");\n require(owner == from, \"not owner in _transferQuad\");\n _owners[id1x1] = uint256(uint160(address(to)));\n } else {\n _regroupQuad(from, to, Land({x: x, y: y, size: size}), true, size / 2);\n }\n for (uint256 i = 0; i < size * size; i++) {\n emit Transfer(from, to, _idInPath(i, size, x, y));\n }\n }\n\n function _mintQuad(\n address to,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes memory data\n ) internal {\n require(to != address(0), \"to is zero address\");\n\n (uint256 layer, , ) = _getQuadLayer(size);\n uint256 quadId = _getQuadId(layer, x, y);\n\n _checkOwner(size, x, y, 24);\n for (uint256 i = 0; i < size * size; i++) {\n uint256 _id = _idInPath(i, size, x, y);\n require(_owners[_id] == 0, \"Already minted\");\n emit Transfer(address(0), to, _id);\n }\n\n _owners[quadId] = uint256(uint160(to));\n _numNFTPerAddress[to] += size * size;\n\n _checkBatchReceiverAcceptQuad(msg.sender, address(0), to, size, x, y, data);\n }\n\n /**\n * @dev checks if the child quads in the parent quad (size, x, y) are owned by msg.sender.\n * It recursively checks child quad of every size(exculding Lands of 1x1 size) are minted or not.\n * Quad which are minted are pushed into quadMinted to also check if every Land of size 1x1 in\n * the parent quad is minted or not. While checking if the every child Quad and Land is minted it\n * also checks and clear the owner for quads which are minted. Finally it checks if the new owner\n * if is a contract can handle ERC721 tokens or not and transfers the parent quad to new owner.\n * @param to The address to which the ownership of the quad will be transferred\n * @param size The size of the quad being minted and transfered\n * @param x The x-coordinate of the top-left corner of the quad being minted.\n * @param y The y-coordinate of the top-left corner of the quad being minted.\n * @param y The y-coordinate of the top-left corner of the quad being minted.\n */\n function _mintAndTransferQuad(\n address to,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes memory data\n ) internal {\n (uint256 layer, , ) = _getQuadLayer(size);\n uint256 quadId = _getQuadId(layer, x, y);\n\n // Length of array is equal to number of 3x3 child quad a 24x24 quad can have. Would be used to push the minted Quads.\n Land[] memory quadMinted = new Land[](64);\n // index of last minted quad pushed on quadMinted Array\n uint256 index;\n uint256 landMinted;\n\n // if size of the Quad in land struct to be transfered is greater than 3 we check recursivly if the child quads are minted or not.\n if (size > 3) {\n (index, landMinted) = _checkAndClearOwner(\n Land({x: x, y: y, size: size}),\n quadMinted,\n landMinted,\n index,\n size / 2\n );\n }\n\n // Lopping around the Quad in land struct to generate ids of 1x1 land token and checking if they are owned by msg.sender\n {\n for (uint256 i = 0; i < size * size; i++) {\n uint256 _id = _idInPath(i, size, x, y);\n // checking land with token id \"_id\" is in the quadMinted array.\n bool isAlreadyMinted = _isQuadMinted(quadMinted, Land({x: _getX(_id), y: _getY(_id), size: 1}), index);\n if (isAlreadyMinted) {\n // if land is in the quadMinted array there just emitting transfer event\n emit Transfer(msg.sender, to, _id);\n } else {\n if (address(uint160(_owners[_id])) == msg.sender) {\n if (_operators[_id] != address(0)) _operators[_id] = address(0);\n landMinted += 1;\n emit Transfer(msg.sender, to, _id);\n } else {\n // else is checked if owned by the msg.sender or not. If it is not owned by msg.sender it should not have an owner.\n require(_owners[_id] == 0, \"Already minted\");\n\n emit Transfer(address(0), to, _id);\n }\n }\n }\n }\n\n // checking if the new owner \"to\" is a contract. If yes, checking if it could handle ERC721 tokens.\n _checkBatchReceiverAcceptQuadAndClearOwner(quadMinted, index, landMinted, to, size, x, y, data);\n\n _owners[quadId] = uint256(uint160(to));\n _numNFTPerAddress[to] += size * size;\n _numNFTPerAddress[msg.sender] -= landMinted;\n }\n\n /**\n * @dev recursivly checks if the child quads are minted in land and push them to the quadMinted array.\n * if a child quad is minted in land such quads child quads will be skipped such that there is no overlapping\n * in quads which are minted. it clears the minted child quads owners.\n * @param land the stuct which has the size x and y co-ordinate of Quad to be checked\n * @param quadMinted array in which the minted child quad would be pushed\n * @param landMinted total 1x1 land already minted\n * @param index index of last element of quadMinted array\n * @param quadCompareSize the size of the child quads to be checked.\n * @return the index of last quad pushed in quadMinted array and the total land already minted\n */\n function _checkAndClearOwner(\n Land memory land,\n Land[] memory quadMinted,\n uint256 landMinted,\n uint256 index,\n uint256 quadCompareSize\n ) internal returns (uint256, uint256) {\n (uint256 layer, , ) = _getQuadLayer(quadCompareSize);\n uint256 toX = land.x + land.size;\n uint256 toY = land.y + land.size;\n\n //Lopping around the Quad in land struct to check if the child quad are minted or not\n for (uint256 xi = land.x; xi < toX; xi += quadCompareSize) {\n for (uint256 yi = land.y; yi < toY; yi += quadCompareSize) {\n //checking if the child Quad is minted or not. i.e Checks if the quad is in the quadMinted array.\n bool isQuadChecked = _isQuadMinted(quadMinted, Land({x: xi, y: yi, size: quadCompareSize}), index);\n // if child quad is not already in the quadMinted array.\n if (!isQuadChecked) {\n uint256 id = _getQuadId(layer, xi, yi);\n address owner = address(uint160(_owners[id]));\n // owner of the child quad is checked to be owned by msg.sender else should not be owned by anyone.\n if (owner == msg.sender) {\n // if child quad is minted it would be pushed in quadMinted array.\n quadMinted[index] = Land({x: xi, y: yi, size: quadCompareSize});\n // index of quadMinted is increased\n index++;\n // total land minted is increase by the number if land of 1x1 in child quad\n landMinted += quadCompareSize * quadCompareSize;\n //owner is cleared\n _owners[id] = 0;\n } else {\n require(owner == address(0), \"Already minted\");\n }\n }\n }\n }\n\n // size of the child quad is set to be the next smaller child quad size (12 => 6 => 3)\n quadCompareSize = quadCompareSize / 2;\n // if child quad size is greater than 3 _checkAndClearOwner is checked for new child quads in the quad in land struct.\n if (quadCompareSize >= 3)\n (index, landMinted) = _checkAndClearOwner(land, quadMinted, landMinted, index, quadCompareSize);\n return (index, landMinted);\n }\n\n /// @dev checks the owner of land with 'tokenId' to be 'from' and clears it\n /// @param from the address to be checked agains the owner of the land\n /// @param tokenId th id of land\n /// @return bool for if land is owned by 'from' or not.\n function _checkAndClearLandOwner(address from, uint256 tokenId) internal returns (bool) {\n uint256 currentOwner = _owners[tokenId];\n if (currentOwner != 0) {\n require((currentOwner & BURNED_FLAG) != BURNED_FLAG, \"not owner\");\n require(address(uint160(currentOwner)) == from, \"not owner\");\n _owners[tokenId] = 0;\n return true;\n }\n return false;\n }\n\n function _checkBatchReceiverAcceptQuad(\n address operator,\n address from,\n address to,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes memory data\n ) internal {\n if (to.isContract() && _checkInterfaceWith10000Gas(to, ERC721_MANDATORY_RECEIVER)) {\n uint256[] memory ids = new uint256[](size * size);\n for (uint256 i = 0; i < size * size; i++) {\n ids[i] = _idInPath(i, size, x, y);\n }\n require(_checkOnERC721BatchReceived(operator, from, to, ids, data), \"erc721 batch transfer rejected by to\");\n }\n }\n\n /// @dev checks if the receiver of the quad(size, x, y) is a contact. If yes can it handle ERC721 tokens. It also clears owner of 1x1 land's owned by msg.sender.\n /// @param quadMinted - an array of Land structs in which the minted child quad or Quad to be transfered are.\n /// @param landMinted - the total amount of land that has been minted\n /// @param index - the index of the last element in the quadMinted array\n /// @param to the address of the new owner of Quad to be transfered\n /// @param size The size of the quad being minted and transfered\n /// @param x The x-coordinate of the top-left corner of the quad being minted.\n /// @param y The y-coordinate of the top-left corner of the quad being minted.\n /// @param y The y-coordinate of the top-left corner of the quad being minted.\n function _checkBatchReceiverAcceptQuadAndClearOwner(\n Land[] memory quadMinted,\n uint256 index,\n uint256 landMinted,\n address to,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes memory data\n ) internal {\n // checks if to is a contract and supports ERC721_MANDATORY_RECEIVER interfaces. if it doesn't it just clears the owner of 1x1 lands in quad(size, x, y)\n if (to.isContract() && _checkInterfaceWith10000Gas(to, ERC721_MANDATORY_RECEIVER)) {\n // array to push minted 1x1 land\n uint256[] memory idsToTransfer = new uint256[](landMinted);\n // index of last land pushed in idsToTransfer array\n uint256 transferIndex;\n // array to push ids to be minted\n uint256[] memory idsToMint = new uint256[]((size * size) - landMinted);\n // index of last land pushed in idsToMint array\n uint256 mintIndex;\n\n // iterating over every 1x1 land in the quad to be pushed in the above arrays\n for (uint256 i = 0; i < size * size; i++) {\n uint256 id = _idInPath(i, size, x, y);\n\n if (_isQuadMinted(quadMinted, Land({x: _getX(id), y: _getY(id), size: 1}), index)) {\n // if land is in the quads already minted it just pushed in to the idsToTransfer array\n idsToTransfer[transferIndex] = id;\n transferIndex++;\n } else if (address(uint160(_owners[id])) == msg.sender) {\n // if it is owned by the msg.sender owner data is removed and it is pused in to idsToTransfer array\n _owners[id] = 0;\n idsToTransfer[transferIndex] = id;\n transferIndex++;\n } else {\n // else it is not owned by any one and and pushed in teh idsToMint array\n idsToMint[mintIndex] = id;\n mintIndex++;\n }\n }\n\n // checking if \"to\" contact can handle ERC721 tokens\n require(\n _checkOnERC721BatchReceived(msg.sender, address(0), to, idsToMint, data),\n \"erc721 batch transfer rejected by to\"\n );\n require(\n _checkOnERC721BatchReceived(msg.sender, msg.sender, to, idsToTransfer, data),\n \"erc721 batch transfer rejected by to\"\n );\n } else {\n for (uint256 i = 0; i < size * size; i++) {\n uint256 id = _idInPath(i, size, x, y);\n if (address(uint160(_owners[id])) == msg.sender) _owners[id] = 0;\n }\n }\n }\n\n function _getX(uint256 id) internal pure returns (uint256) {\n return (id & ~LAYER) % GRID_SIZE;\n }\n\n function _getY(uint256 id) internal pure returns (uint256) {\n return (id & ~LAYER) / GRID_SIZE;\n }\n\n function _isQuadMinted(\n Land[] memory mintedLand,\n Land memory quad,\n uint256 index\n ) internal pure returns (bool) {\n for (uint256 i = 0; i < index; i++) {\n Land memory land = mintedLand[i];\n if (\n land.size > quad.size &&\n quad.x >= land.x &&\n quad.x < land.x + land.size &&\n quad.y >= land.y &&\n quad.y < land.y + land.size\n ) {\n return true;\n }\n }\n return false;\n }\n\n function _getQuadLayer(uint256 size)\n internal\n pure\n returns (\n uint256 layer,\n uint256 parentSize,\n uint256 childLayer\n )\n {\n if (size == 1) {\n layer = LAYER_1x1;\n parentSize = 3;\n } else if (size == 3) {\n layer = LAYER_3x3;\n parentSize = 6;\n } else if (size == 6) {\n layer = LAYER_6x6;\n parentSize = 12;\n childLayer = LAYER_3x3;\n } else if (size == 12) {\n layer = LAYER_12x12;\n parentSize = 24;\n childLayer = LAYER_6x6;\n } else if (size == 24) {\n layer = LAYER_24x24;\n childLayer = LAYER_12x12;\n } else {\n require(false, \"Invalid size\");\n }\n }\n\n function _getQuadId(\n uint256 layer,\n uint256 x,\n uint256 y\n ) internal pure returns (uint256) {\n return layer + x + y * GRID_SIZE;\n }\n\n function _checkOwner(\n uint256 size,\n uint256 x,\n uint256 y,\n uint256 quadCompareSize\n ) internal view {\n (uint256 layer, , ) = _getQuadLayer(quadCompareSize);\n\n if (size <= quadCompareSize) {\n // when the size of the quad is smaller than the quadCompareSize(size to be compared with),\n // then it is checked if the bigger quad which encapsulates the quad to be minted\n // of with size equals the quadCompareSize has been minted or not\n require(\n _owners[\n _getQuadId(layer, (x / quadCompareSize) * quadCompareSize, (y / quadCompareSize) * quadCompareSize)\n ] == 0,\n \"Already minted\"\n );\n } else {\n // when the size is smaller than the quadCompare size the owner of all the smaller quads with size\n // quadCompare size in the quad to be minted are checked if they are minted or not\n uint256 toX = x + size;\n uint256 toY = y + size;\n for (uint256 xi = x; xi < toX; xi += quadCompareSize) {\n for (uint256 yi = y; yi < toY; yi += quadCompareSize) {\n require(_owners[_getQuadId(layer, xi, yi)] == 0, \"Already minted\");\n }\n }\n }\n\n quadCompareSize = quadCompareSize / 2;\n if (quadCompareSize >= 3) _checkOwner(size, x, y, quadCompareSize);\n }\n\n function _idInPath(\n uint256 i,\n uint256 size,\n uint256 x,\n uint256 y\n ) internal pure returns (uint256) {\n uint256 row = i / size;\n if (row % 2 == 0) {\n // allow ids to follow a path in a quad\n return _getQuadId(LAYER_1x1, (x + (i % size)), (y + row));\n } else {\n return _getQuadId(LAYER_1x1, (x + size) - (1 + (i % size)), (y + row));\n }\n }\n\n /// @dev checks if the Land's child quads are owned by the from address and clears all the previous owners\n /// if all the child quads are not owned by the \"from\" address then the owner of parent quad to the land\n /// is checked if owned by the \"from\" address. If from is the owner then land owner is set to \"to\" address\n /// @param from address of the previous owner\n /// @param to address of the new owner\n /// @param land the quad to be regrouped and transferred\n /// @param set for setting the new owner\n /// @param childQuadSize size of the child quad to be checked for owner in the regrouping\n function _regroupQuad(\n address from,\n address to,\n Land memory land,\n bool set,\n uint256 childQuadSize\n ) internal returns (bool) {\n (uint256 layer, , uint256 childLayer) = _getQuadLayer(land.size);\n uint256 quadId = _getQuadId(layer, land.x, land.y);\n bool ownerOfAll = true;\n\n {\n // double for loop iterates and checks owner of all the smaller quads in land\n for (uint256 xi = land.x; xi < land.x + land.size; xi += childQuadSize) {\n for (uint256 yi = land.y; yi < land.y + land.size; yi += childQuadSize) {\n uint256 ownerChild;\n bool ownAllIndividual;\n if (childQuadSize < 3) {\n // case when the smaller quad is 1x1,\n ownAllIndividual = _checkAndClearLandOwner(from, _getQuadId(LAYER_1x1, xi, yi)) && ownerOfAll;\n } else {\n // recursively calling the _regroupQuad function to check the owner of child quads.\n ownAllIndividual = _regroupQuad(\n from,\n to,\n Land({x: xi, y: yi, size: childQuadSize}),\n false,\n childQuadSize / 2\n );\n uint256 idChild = _getQuadId(childLayer, xi, yi);\n ownerChild = _owners[idChild];\n if (ownerChild != 0) {\n // checking the owner of child quad\n if (!ownAllIndividual) {\n require(ownerChild == uint256(uint160(from)), \"not owner of child Quad\");\n }\n // clearing owner of child quad\n _owners[idChild] = 0;\n }\n }\n // ownerOfAll should be true if \"from\" is owner of all the child quads itereated over\n ownerOfAll = (ownAllIndividual || ownerChild != 0) && ownerOfAll;\n }\n }\n }\n\n // if set is true it check if the \"from\" is owner of all else checks for the owner of parent quad is\n // owned by \"from\" and sets the owner for the id of land to \"to\" address.\n if (set) {\n if (!ownerOfAll) {\n require(_ownerOfQuad(land.size, land.x, land.y) == from, \"not owner of all sub quads nor parent quads\");\n }\n _owners[quadId] = uint256(uint160(to));\n return true;\n }\n\n return ownerOfAll;\n }\n\n function _ownerOfQuad(\n uint256 size,\n uint256 x,\n uint256 y\n ) internal view returns (address) {\n (uint256 layer, uint256 parentSize, ) = _getQuadLayer(size);\n address owner = address(uint160(_owners[_getQuadId(layer, (x / size) * size, (y / size) * size)]));\n if (owner != address(0)) {\n return owner;\n } else if (size < 24) {\n return _ownerOfQuad(parentSize, x, y);\n }\n return address(0);\n }\n\n function _getQuadById(uint256 id)\n internal\n pure\n returns (\n uint256 size,\n uint256 x,\n uint256 y\n )\n {\n x = _getX(id);\n y = _getY(id);\n uint256 layer = id & LAYER;\n if (layer == LAYER_1x1) {\n size = 1;\n } else if (layer == LAYER_3x3) {\n size = 3;\n } else if (layer == LAYER_6x6) {\n size = 6;\n } else if (layer == LAYER_12x12) {\n size = 12;\n } else if (layer == LAYER_24x24) {\n size = 24;\n } else {\n require(false, \"Invalid token id\");\n }\n }\n\n function _ownerOf(uint256 id) internal view override returns (address) {\n require(id & LAYER == 0, \"Invalid token id\");\n (uint256 size, uint256 x, uint256 y) = _getQuadById(id);\n require(x % size == 0, \"x coordinate: Invalid token id\");\n require(y % size == 0, \"y coordinate: Invalid token id\");\n if (size == 1) {\n uint256 owner1x1 = _owners[id];\n return (owner1x1 & BURNED_FLAG) == BURNED_FLAG ? address(0) : _ownerOfQuad(size, x, y);\n }\n return _ownerOfQuad(size, x, y);\n }\n\n function _ownerAndOperatorEnabledOf(uint256 id)\n internal\n view\n override\n returns (address owner, bool operatorEnabled)\n {\n require(id & LAYER == 0, \"Invalid token id\");\n uint256 x = id % GRID_SIZE;\n uint256 y = id / GRID_SIZE;\n uint256 owner1x1 = _owners[id];\n\n if ((owner1x1 & BURNED_FLAG) == BURNED_FLAG) {\n owner = address(0);\n operatorEnabled = (owner1x1 & OPERATOR_FLAG) == OPERATOR_FLAG;\n return (owner, operatorEnabled);\n }\n\n if (owner1x1 != 0) {\n owner = address(uint160(owner1x1));\n operatorEnabled = (owner1x1 & OPERATOR_FLAG) == OPERATOR_FLAG;\n } else {\n owner = _ownerOfQuad(3, (x * 3) / 3, (y * 3) / 3);\n operatorEnabled = false;\n }\n }\n\n // Empty storage space in contracts for future enhancements\n // ref: https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/issues/13)\n uint256[49] private __gap;\n}\n" + }, + "src/solc_0.8/polygon/child/land/PolygonLandTunnel.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"fx-portal/contracts/tunnel/FxBaseChildTunnel.sol\";\nimport \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\nimport \"@openzeppelin/contracts-0.8/security/Pausable.sol\";\n\nimport \"../../../common/interfaces/IPolygonLand.sol\";\nimport \"../../../common/interfaces/IERC721MandatoryTokenReceiver.sol\";\nimport \"../../../common/BaseWithStorage/ERC2771Handler.sol\";\nimport \"./PolygonLandBaseToken.sol\";\n\n/// @title LAND bridge on L2\ncontract PolygonLandTunnel is FxBaseChildTunnel, IERC721MandatoryTokenReceiver, ERC2771Handler, Ownable, Pausable {\n IPolygonLand public immutable childToken;\n uint32 public maxGasLimitOnL1;\n uint256 public maxAllowedQuads;\n bool internal transferringToL1;\n\n mapping(uint8 => uint32) public gasLimits;\n\n event SetGasLimit(uint8 size, uint32 limit);\n event SetMaxGasLimit(uint32 maxGasLimit);\n event SetMaxAllowedQuads(uint256 maxQuads);\n event Deposit(address indexed user, uint256 size, uint256 x, uint256 y, bytes data);\n event Withdraw(address indexed user, uint256 size, uint256 x, uint256 y, bytes data);\n\n function setMaxLimitOnL1(uint32 _maxGasLimit) external onlyOwner {\n maxGasLimitOnL1 = _maxGasLimit;\n emit SetMaxGasLimit(_maxGasLimit);\n }\n\n function setMaxAllowedQuads(uint256 _maxAllowedQuads) external onlyOwner {\n require(_maxAllowedQuads > 0, \"PolygonLandTunnel: max allowed value cannot be zero\");\n maxAllowedQuads = _maxAllowedQuads;\n emit SetMaxAllowedQuads(_maxAllowedQuads);\n }\n\n function _setLimit(uint8 size, uint32 limit) internal {\n gasLimits[size] = limit;\n emit SetGasLimit(size, limit);\n }\n\n function setLimit(uint8 size, uint32 limit) external onlyOwner {\n _setLimit(size, limit);\n }\n\n // setupLimits([5, 10, 20, 90, 340]);\n function setupLimits(uint32[5] memory limits) public onlyOwner {\n _setLimit(1, limits[0]);\n _setLimit(3, limits[1]);\n _setLimit(6, limits[2]);\n _setLimit(12, limits[3]);\n _setLimit(24, limits[4]);\n }\n\n constructor(\n address _fxChild,\n IPolygonLand _childToken,\n address _trustedForwarder,\n uint32 _maxGasLimit,\n uint256 _maxAllowedQuads,\n uint32[5] memory limits\n ) FxBaseChildTunnel(_fxChild) {\n childToken = _childToken;\n maxGasLimitOnL1 = _maxGasLimit;\n maxAllowedQuads = _maxAllowedQuads;\n setupLimits(limits);\n __ERC2771Handler_initialize(_trustedForwarder);\n }\n\n function batchTransferQuadToL1(\n address to,\n uint256[] calldata sizes,\n uint256[] calldata xs,\n uint256[] calldata ys,\n bytes memory data\n ) external whenNotPaused() {\n require(sizes.length == xs.length && sizes.length == ys.length, \"sizes, xs, ys must be same length\");\n\n uint32 gasLimit = 0;\n uint256 quads = 0;\n for (uint256 i = 0; i < sizes.length; i++) {\n gasLimit += gasLimits[uint8(sizes[i])];\n quads += sizes[i] * sizes[i];\n }\n\n require(quads <= maxAllowedQuads, \"Exceeds max allowed quads.\");\n require(gasLimit < maxGasLimitOnL1, \"Exceeds gas limit on L1.\");\n transferringToL1 = true;\n for (uint256 i = 0; i < sizes.length; i++) {\n childToken.transferQuad(_msgSender(), address(this), sizes[i], xs[i], ys[i], data);\n emit Withdraw(to, sizes[i], xs[i], ys[i], data);\n }\n _sendMessageToRoot(abi.encode(to, sizes, xs, ys, data));\n transferringToL1 = false;\n }\n\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyOwner {\n _trustedForwarder = trustedForwarder;\n }\n\n /// @dev Pauses all token transfers across bridge\n function pause() external onlyOwner {\n _pause();\n }\n\n /// @dev Unpauses all token transfers across bridge\n function unpause() external onlyOwner {\n _unpause();\n }\n\n function _processMessageFromRoot(\n uint256, /* stateId */\n address sender,\n bytes memory data\n ) internal override validateSender(sender) {\n _syncDeposit(data);\n }\n\n function _syncDeposit(bytes memory syncData) internal {\n (address to, uint256 size, uint256 x, uint256 y, bytes memory data) =\n abi.decode(syncData, (address, uint256, uint256, uint256, bytes));\n if (!childToken.exists(size, x, y)) childToken.mintQuad(to, size, x, y, data);\n else childToken.transferQuad(address(this), to, size, x, y, data);\n emit Deposit(to, size, x, y, data);\n }\n\n function _msgSender() internal view override(Context, ERC2771Handler) returns (address sender) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view override(Context, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n\n function onERC721Received(\n address, /* operator */\n address, /* from */\n uint256, /* tokenId */\n bytes calldata /* data */\n ) external view override returns (bytes4) {\n require(transferringToL1, \"PolygonLandTunnel: !BRIDGING\");\n return this.onERC721Received.selector;\n }\n\n function onERC721BatchReceived(\n address, /* operator */\n address, /* from */\n uint256[] calldata, /* ids */\n bytes calldata /* data */\n ) external view override returns (bytes4) {\n require(transferringToL1, \"PolygonLandTunnel: !BRIDGING\");\n return this.onERC721BatchReceived.selector;\n }\n\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return interfaceId == 0x5e8bf644 || interfaceId == 0x01ffc9a7;\n }\n}\n" + }, + "src/solc_0.8/polygon/child/land/PolygonLandTunnelMigration.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {IPolygonLandWithSetApproval} from \"../../../common/interfaces/IPolygonLandWithSetApproval.sol\";\nimport {IPolygonLandTunnel} from \"../../../common/interfaces/IPolygonLandTunnel.sol\";\nimport {IERC721MandatoryTokenReceiver} from \"../../../common/interfaces/IERC721MandatoryTokenReceiver.sol\";\n\n/// @title Tunnel migration on L2\n/// @author The Sandbox\n/// @notice contract handling the migration of LAND tokens from a tunnel to a new one\ncontract PolygonLandTunnelMigration is IERC721MandatoryTokenReceiver {\n struct OwnerWithLandIds {\n address owner;\n uint256[] sizes;\n uint256[] x;\n uint256[] y;\n }\n\n IPolygonLandWithSetApproval public immutable polygonLand;\n address public immutable newLandTunnel;\n address public immutable oldLandTunnel;\n address private admin;\n\n event TunnelLandsMigrated(address indexed oldLandTunnel, address indexed newLandTunnel, uint256[] ids);\n event TunnelLandsMigratedWithWithdraw(OwnerWithLandIds indexed _ownerWithLandIds);\n event TunnelQuadsMigrated(\n address indexed oldLandTunnel,\n address indexed newLandTunnel,\n uint256[] sizes,\n uint256[] x,\n uint256[] y\n );\n event AdminChanged(address indexed _newAdmin);\n\n modifier isAdmin() {\n require(admin == msg.sender, \"PolygonLandTunnelMigration: !AUTHORISED\");\n _;\n }\n\n /// @notice constructor of the tunnel migration contract\n /// @param _polygonLand LAND token address on the child chain\n /// @param _newLandTunnel tunnel address to migrate to\n /// @param _oldLandTunnel tunnel address to migrate from\n /// @param _admin admin of the contract\n constructor(\n address _polygonLand,\n address _newLandTunnel,\n address _oldLandTunnel,\n address _admin\n ) {\n require(_admin != address(0), \"PolygonLandTunnelMigration: admin can't be zero address\");\n require(_polygonLand != address(0), \"PolygonLandTunnelMigration: polygonLand can't be zero address\");\n require(_newLandTunnel != address(0), \"PolygonLandTunnelMigration: new Tunnel can't be zero address\");\n require(_oldLandTunnel != address(0), \"PolygonLandTunnelMigration: old Tunnel can't be zero address\");\n admin = _admin;\n polygonLand = IPolygonLandWithSetApproval(_polygonLand);\n newLandTunnel = _newLandTunnel;\n oldLandTunnel = _oldLandTunnel;\n\n emit AdminChanged(_admin);\n }\n\n /// @dev Transfers all the passed land ids from the old land tunnel to the new land tunnel\n /// @notice This method needs super operator role to execute\n /// @param ids of land tokens to be migrated\n function migrateLandsToTunnel(uint256[] memory ids) external isAdmin {\n polygonLand.batchTransferFrom(oldLandTunnel, newLandTunnel, ids, \"\");\n emit TunnelLandsMigrated(oldLandTunnel, newLandTunnel, ids);\n }\n\n /// @dev Fetches locked land ids to this contract and withdraws again through the new tunnel\n /// @notice This method needs super operator role to execute\n /// @param _ownerWithLandIds struct containing token owner with their land ids\n function migrateToTunnelWithWithdraw(OwnerWithLandIds memory _ownerWithLandIds) external isAdmin {\n // check for gas limits based on the number of locked tokens\n // Fetch locked tokens to this contract address\n polygonLand.batchTransferQuad(\n oldLandTunnel,\n address(this),\n _ownerWithLandIds.sizes,\n _ownerWithLandIds.x,\n _ownerWithLandIds.y,\n \"\"\n );\n // Withdraw tokens to L1\n IPolygonLandTunnel(newLandTunnel).batchTransferQuadToL1(\n _ownerWithLandIds.owner,\n _ownerWithLandIds.sizes,\n _ownerWithLandIds.x,\n _ownerWithLandIds.y,\n \"\"\n );\n\n emit TunnelLandsMigratedWithWithdraw(_ownerWithLandIds);\n }\n\n ///@dev approves New Land Tunnel to transfer Lands on behalf of this contract\n function approveNewLandTunnel() external isAdmin {\n polygonLand.setApprovalForAll(newLandTunnel, true);\n }\n\n /// @dev Transfers all the passed quads from the old land tunnel to the new land tunnel\n /// @notice This method needs super operator role to execute\n /// @param sizes of land quads to be migrated\n /// @param x coordinate of land quads to be migrated\n /// @param y coordinate of land quads to be migrated\n function migrateQuadsToTunnel(\n uint256[] memory sizes,\n uint256[] memory x,\n uint256[] memory y\n ) external isAdmin {\n polygonLand.batchTransferQuad(oldLandTunnel, newLandTunnel, sizes, x, y, \"\");\n emit TunnelQuadsMigrated(oldLandTunnel, newLandTunnel, sizes, x, y);\n }\n\n /// @notice changes admin to new admin\n /// @param _newAdmin the new admin to be set\n function changeAdmin(address _newAdmin) external isAdmin {\n require(_newAdmin != address(0), \"PolygonLandTunnelMigration: admin can't be zero address\");\n admin = _newAdmin;\n emit AdminChanged(_newAdmin);\n }\n\n /// @dev called on ERC721 transfer to this contract\n /// @return onERC721Received function selector\n function onERC721Received(\n address, /* operator */\n address, /* from */\n uint256, /* tokenId */\n bytes calldata /* data */\n ) external pure override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n\n /// @dev called on ERC721 batch transfer to this contract\n /// @return onERC721BatchReceived function selector\n function onERC721BatchReceived(\n address, /* operator */\n address, /* from */\n uint256[] calldata, /* ids */\n bytes calldata /* data */\n ) external pure override returns (bytes4) {\n return this.onERC721BatchReceived.selector;\n }\n\n /// @dev to be called by external contact to check if this contract supports ERC721 token and batch token receive\n /// @param interfaceId the interface to be checked if supported by the contract\n /// @return 0x5e8bf644 is the interface of IERC721MandatoryTokenReceiver and 0x01ffc9a7 for the Eip 165 supports interface's interface id\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return interfaceId == 0x5e8bf644 || interfaceId == 0x01ffc9a7;\n }\n}\n" + }, + "src/solc_0.8/polygon/child/land/PolygonLandTunnelV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {FxBaseChildTunnelUpgradeable} from \"../../../common/fx-portal/FxBaseChildTunnelUpgradeable.sol\";\nimport {\n OwnableUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {IPolygonLandV2} from \"../../../common/interfaces/IPolygonLandV2.sol\";\nimport {IERC721MandatoryTokenReceiver} from \"../../../common/interfaces/IERC721MandatoryTokenReceiver.sol\";\nimport {ERC2771Handler} from \"../../../common/BaseWithStorage/ERC2771Handler.sol\";\n\n/**\n * @title PolygonLandTunnelV2\n * @author The Sandbox\n * @notice LAND tunnel on the child chain\n */\ncontract PolygonLandTunnelV2 is\n FxBaseChildTunnelUpgradeable,\n IERC721MandatoryTokenReceiver,\n ERC2771Handler,\n OwnableUpgradeable,\n PausableUpgradeable\n{\n bool internal transferringToL1;\n uint32 public maxGasLimitOnL1;\n uint256 public maxAllowedLands;\n IPolygonLandV2 public childToken;\n\n mapping(uint8 => uint32) public gasLimits;\n\n event SetGasLimit(uint8 indexed size, uint32 indexed limit);\n event SetMaxGasLimit(uint32 maxGasLimit);\n event SetMaxAllowedLands(uint256 maxLands);\n event Deposit(address indexed user, uint256 size, uint256 x, uint256 y, bytes data);\n event Withdraw(address indexed user, uint256 size, uint256 x, uint256 y, bytes data);\n\n /// @notice initialize the contract\n /// @param _fxChild child contract for state receiver\n /// @param _childToken address of the token on the child chain\n /// @param _trustedForwarder address of an ERC2771 meta transaction sender contract\n /// @param _maxGasLimit maximum accepted gas limit\n /// @param _maxAllowedLands maximum number of Lands accepted\n /// @param limits the estimated gas that the L1 tx will use per quad size\n function initialize(\n address _fxChild,\n IPolygonLandV2 _childToken,\n address _trustedForwarder,\n uint32 _maxGasLimit,\n uint256 _maxAllowedLands,\n uint32[5] memory limits\n ) public initializer {\n __Ownable_init();\n __Pausable_init();\n childToken = _childToken;\n _setMaxLimitOnL1(_maxGasLimit);\n _setMaxAllowedLands(_maxAllowedLands);\n setupGasLimits(limits);\n __FxBaseChildTunnelUpgradeable_initialize(_fxChild);\n __ERC2771Handler_initialize(_trustedForwarder);\n }\n\n /// @notice set the limit of lands we can send in one tx to L1\n /// @param _maxAllowedLands maximum number of lands accepted\n function setMaxAllowedLands(uint256 _maxAllowedLands) external onlyOwner {\n require(_maxAllowedLands > 0, \"PolygonLandTunnelV2: max allowed value cannot be zero\");\n maxAllowedLands = _maxAllowedLands;\n emit SetMaxAllowedLands(_maxAllowedLands);\n }\n\n /// @notice set the estimate of gas that the L1 transaction will use per quad size\n /// @param size the size of the quad\n /// @param limit the estimated gas that the L1 tx will use\n function setGasLimit(uint8 size, uint32 limit) external onlyOwner {\n require(size == 1 || size == 3 || size == 6 || size == 12 || size == 24, \"PolygonLandTunnelV2: invalid data\");\n\n _setGasLimit(size, limit);\n }\n\n /// @notice set the estimate of gas that the L1 transaction will use per quad size\n /// @param limits the estimated gas that the L1 tx will use per quad size\n function setupGasLimits(uint32[5] memory limits) public onlyOwner {\n _setGasLimit(1, limits[0]);\n _setGasLimit(3, limits[1]);\n _setGasLimit(6, limits[2]);\n _setGasLimit(12, limits[3]);\n _setGasLimit(24, limits[4]);\n }\n\n /// @notice send a batch of quads to L1\n /// @param to address of the receiver on L1\n /// @param sizes sizes of quad\n /// @param xs x coordinates of quads\n /// @param ys y coordinates of quads\n /// @param data data send to the receiver onERC721BatchReceived on L1\n function batchTransferQuadToL1(\n address to,\n uint256[] calldata sizes,\n uint256[] calldata xs,\n uint256[] calldata ys,\n bytes memory data\n ) external whenNotPaused() {\n require(to != address(0), \"PolygonLandTunnelV2: can't send to zero address\");\n require(sizes.length == xs.length, \"PolygonLandTunnelV2: sizes's and x's length are different\");\n require(sizes.length == ys.length, \"PolygonLandTunnelV2: x's and y's length are different\");\n\n uint32 totalGasLimit = 0;\n uint256 lands = 0;\n for (uint256 i = 0; i < sizes.length; i++) {\n totalGasLimit += gasLimits[uint8(sizes[i])];\n lands += sizes[i] * sizes[i];\n }\n\n require(lands <= maxAllowedLands, \"PolygonLandTunnelV2: Exceeds max allowed lands.\");\n require(totalGasLimit < maxGasLimitOnL1, \"PolygonLandTunnelV2: Exceeds gas limit on L1.\");\n transferringToL1 = true;\n for (uint256 i = 0; i < sizes.length; i++) {\n childToken.transferQuad(_msgSender(), address(this), sizes[i], xs[i], ys[i], data);\n emit Withdraw(to, sizes[i], xs[i], ys[i], data);\n }\n _sendMessageToRoot(abi.encode(to, sizes, xs, ys, data));\n transferringToL1 = false;\n }\n\n /// @notice sets the fx-root tunnel\n /// @dev only owner can call this funtion\n /// @param _fxRootTunnel address of the fx-root tunnel\n function setFxRootTunnel(address _fxRootTunnel) external override onlyOwner {\n require(fxRootTunnel == address(0), \"PolygonLandTunnelV2: ROOT_TUNNEL_ALREADY_SET\");\n\n fxRootTunnel = _fxRootTunnel;\n }\n\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyOwner {\n _trustedForwarder = trustedForwarder;\n\n emit TrustedForwarderSet(trustedForwarder);\n }\n\n /// @notice set the limit of estimated gas we accept when sending a batch of quads to L1\n /// @param _maxGasLimit maximum accepted gas limit\n function setMaxLimitOnL1(uint32 _maxGasLimit) external onlyOwner {\n _setMaxLimitOnL1(_maxGasLimit);\n }\n\n /// @dev Pauses all token transfers across bridge\n function pause() external onlyOwner {\n _pause();\n }\n\n /// @dev Unpauses all token transfers across bridge\n function unpause() external onlyOwner {\n _unpause();\n }\n\n /// @dev called on ERC721 transfer to this contract\n /// @param operator address of the one sending the ERC721 Token\n /// @return onERC721Received function selector\n function onERC721Received(\n address operator,\n address,\n uint256,\n bytes calldata\n ) external view override returns (bytes4) {\n require(transferringToL1 || childToken.isSuperOperator(operator), \"PolygonLandTunnelV2: !BRIDGING\");\n return this.onERC721Received.selector;\n }\n\n /// @dev called on ERC721 batch transfer to this contract\n /// @param operator address of the one sending the ERC721 Token\n /// @return onERC721BatchReceived function selector\n function onERC721BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n bytes calldata\n ) external view override returns (bytes4) {\n require(transferringToL1 || childToken.isSuperOperator(operator), \"PolygonLandTunnelV2: !BRIDGING\");\n return this.onERC721BatchReceived.selector;\n }\n\n /// @dev to be called by external contact to check if this contract supports ERC721 token and batch token receive\n /// @param interfaceId the interface to be checked if supported by the contract\n /// @return 0x5e8bf644 is the interface of IERC721MandatoryTokenReceiver and 0x01ffc9a7 for the Eip 165 supports interface's interface id\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return interfaceId == 0x5e8bf644 || interfaceId == 0x01ffc9a7;\n }\n\n function _processMessageFromRoot(\n uint256,\n address sender,\n bytes memory data\n ) internal override validateSender(sender) {\n _syncDeposit(data);\n }\n\n function _setMaxLimitOnL1(uint32 _maxGasLimit) internal {\n maxGasLimitOnL1 = _maxGasLimit;\n emit SetMaxGasLimit(_maxGasLimit);\n }\n\n function _setMaxAllowedLands(uint256 _maxAllowedLands) internal {\n require(_maxAllowedLands > 0, \"PolygonLandTunnelV2: max allowed value cannot be zero\");\n maxAllowedLands = _maxAllowedLands;\n emit SetMaxAllowedLands(_maxAllowedLands);\n }\n\n function _syncDeposit(bytes memory syncData) internal {\n (address to, uint256 size, uint256 x, uint256 y, bytes memory data) =\n abi.decode(syncData, (address, uint256, uint256, uint256, bytes));\n childToken.mintAndTransferQuad(to, size, x, y, data);\n emit Deposit(to, size, x, y, data);\n }\n\n function _msgSender() internal view override(ContextUpgradeable, ERC2771Handler) returns (address) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n\n function _setGasLimit(uint8 size, uint32 limit) internal {\n gasLimits[size] = limit;\n emit SetGasLimit(size, limit);\n }\n\n uint256[50] private __gap;\n}\n" + }, + "src/solc_0.8/polygon/child/land/PolygonLandV1.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport \"./PolygonLandBaseToken.sol\";\nimport \"../../../common/BaseWithStorage/ERC2771Handler.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\n\n/// @title LAND token on L2\ncontract PolygonLandV1 is PolygonLandBaseToken, ERC2771Handler {\n function initialize(address trustedForwarder) external initializer {\n _admin = _msgSender();\n __ERC2771Handler_initialize(trustedForwarder);\n }\n\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyAdmin {\n _trustedForwarder = trustedForwarder;\n }\n\n function _msgSender() internal view override(ContextUpgradeable, ERC2771Handler) returns (address sender) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n}\n" + }, + "src/solc_0.8/polygon/child/land/PolygonLandV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport \"./PolygonLandBaseTokenV2.sol\";\nimport \"../../../common/BaseWithStorage/ERC2771Handler.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport \"../../../OperatorFilterer/contracts/upgradeable/OperatorFiltererUpgradeable.sol\";\n\n/// @title LAND token on L2\ncontract PolygonLandV2 is PolygonLandBaseTokenV2, ERC2771Handler, OperatorFiltererUpgradeable {\n using AddressUpgradeable for address;\n\n event OperatorRegistrySet(address indexed registry);\n\n function initialize(address trustedForwarder) external initializer {\n _admin = _msgSender();\n __ERC2771Handler_initialize(trustedForwarder);\n emit AdminChanged(address(0), _admin);\n }\n\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyAdmin {\n _trustedForwarder = trustedForwarder;\n emit TrustedForwarderSet(trustedForwarder);\n }\n\n function _msgSender() internal view override(ContextUpgradeable, ERC2771Handler) returns (address) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n\n /**\n * @notice Approve an operator to spend tokens on the sender behalf\n * @param sender The address giving the approval\n * @param operator The address receiving the approval\n * @param id The id of the token\n */\n function approveFor(\n address sender,\n address operator,\n uint256 id\n ) public override onlyAllowedOperatorApproval(operator) {\n super.approveFor(sender, operator, id);\n }\n\n /**\n * @notice Approve an operator to spend tokens on the sender behalf\n * @param operator The address receiving the approval\n * @param id The id of the token\n */\n function approve(address operator, uint256 id) public override onlyAllowedOperatorApproval(operator) {\n super.approve(operator, id);\n }\n\n /**\n * @notice Transfer a token between 2 addresses\n * @param from The sender of the token\n * @param to The recipient of the token\n * @param id The id of the token\n */\n function transferFrom(\n address from,\n address to,\n uint256 id\n ) public override onlyAllowedOperator(from) {\n super.transferFrom(from, to, id);\n }\n\n /**\n * @notice Transfer a token between 2 addresses letting the receiver knows of the transfer\n * @param from The sender of the token\n * @param to The recipient of the token\n * @param id The id of the token\n * @param data Additional data\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super.safeTransferFrom(from, to, id, data);\n }\n\n /**\n * @notice Transfer a token between 2 addresses letting the receiver knows of the transfer\n * @param from The send of the token\n * @param to The recipient of the token\n * @param id The id of the token\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id\n ) public override onlyAllowedOperator(from) {\n super.safeTransferFrom(from, to, id);\n }\n\n /**\n * @notice Set the approval for an operator to manage all the tokens of the sender\n * @param operator The address receiving the approval\n * @param approved The determination of the approval\n */\n function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {\n super.setApprovalForAll(operator, approved);\n }\n\n /**\n * @notice Set the approval for an operator to manage all the tokens of the sender\n * @param sender The address giving the approval\n * @param operator The address receiving the approval\n * @param approved The determination of the approval\n */\n function setApprovalForAllFor(\n address sender,\n address operator,\n bool approved\n ) public override onlyAllowedOperatorApproval(operator) {\n super.setApprovalForAllFor(sender, operator, approved);\n }\n\n /// @notice This function is used to register Land contract on the Operator Filterer Registry of Opensea.\n /// @dev can only be called by admin.\n /// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe.\n /// @param subscribe bool to signify subscription 'true' or to copy the list 'false'.\n function register(address subscriptionOrRegistrantToCopy, bool subscribe) external onlyAdmin {\n require(subscriptionOrRegistrantToCopy != address(0), \"PolygonLandV2: subscription can't be zero address\");\n _register(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n /// @notice sets filter registry address deployed in test\n /// @param registry the address of the registry\n function setOperatorRegistry(address registry) external virtual onlyAdmin {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n emit OperatorRegistrySet(registry);\n }\n}\n" + }, + "src/solc_0.8/polygon/child/sand/interfaces/IPolygonSand.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\ninterface IPolygonSand {\n /// @notice update the ChildChainManager Proxy address\n /// @param newChildChainManagerProxy address of the new childChainManagerProxy\n function updateChildChainManager(address newChildChainManagerProxy) external;\n\n /// @notice called when tokens are deposited on root chain\n /// @param user user address for whom deposit is being done\n /// @param depositData abi encoded amount\n function deposit(address user, bytes calldata depositData) external;\n\n /// @notice called when user wants to withdraw tokens back to root chain\n /// @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n /// @param amount amount to withdraw\n function withdraw(uint256 amount) external;\n\n /// @notice Get the balance of `owner`.\n /// @param owner The address to query the balance of.\n /// @return The amount owned by `owner`.\n function balanceOf(address owner) external returns (uint256);\n\n /// @notice transfer tokens to a specific address.\n /// @param to destination address receiving the tokens.\n /// @param amount number of tokens to transfer.\n /// @return success whether the transfer succeeded.\n function transfer(address to, uint256 amount) external returns (bool success);\n\n /// @notice transfer tokens from one address to another.\n /// @param from address tokens will be sent from.\n /// @param to destination address receiving the tokens.\n /// @param amount number of tokens to transfer.\n /// @return success whether the transfer succeeded.\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool success);\n\n function setTrustedForwarder(address trustedForwarder) external;\n}\n" + }, + "src/solc_0.8/polygon/child/sand/PolygonSand.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\nimport \"../../../common/BaseWithStorage/ERC2771Handler.sol\";\nimport \"../../../Sand/SandBaseToken.sol\";\n\ncontract PolygonSand is SandBaseToken, Ownable, ERC2771Handler {\n address public childChainManagerProxy;\n\n constructor(\n address _childChainManagerProxy,\n address trustedForwarder,\n address sandAdmin,\n address executionAdmin\n ) SandBaseToken(sandAdmin, executionAdmin, address(0), 0) {\n require(_childChainManagerProxy != address(0), \"Bad ChildChainManagerProxy address\");\n childChainManagerProxy = _childChainManagerProxy;\n __ERC2771Handler_initialize(trustedForwarder);\n }\n\n /// @notice update the ChildChainManager Proxy address\n /// @param newChildChainManagerProxy address of the new childChainManagerProxy\n function updateChildChainManager(address newChildChainManagerProxy) external onlyOwner {\n require(newChildChainManagerProxy != address(0), \"Bad ChildChainManagerProxy address\");\n childChainManagerProxy = newChildChainManagerProxy;\n }\n\n /// @notice called when tokens are deposited on root chain\n /// @param user user address for whom deposit is being done\n /// @param depositData abi encoded amount\n function deposit(address user, bytes calldata depositData) external {\n require(_msgSender() == childChainManagerProxy, \"You're not allowed to deposit\");\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /// @notice called when user wants to withdraw tokens back to root chain\n /// @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n /// @param amount amount to withdraw\n function withdraw(uint256 amount) external {\n _burn(_msgSender(), amount);\n }\n\n function setTrustedForwarder(address trustedForwarder) external onlyOwner {\n _trustedForwarder = trustedForwarder;\n }\n\n function _msgSender() internal view override(Context, ERC2771Handler) returns (address sender) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view override(Context, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n}\n" + }, + "src/solc_0.8/polygon/child/sand/PolygonSandClaim.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/security/ReentrancyGuard.sol\";\nimport \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\nimport \"@openzeppelin/contracts-0.8/token/ERC20/IERC20.sol\";\nimport \"./interfaces/IPolygonSand.sol\";\n\ncontract PolygonSandClaim is Ownable, ReentrancyGuard {\n IPolygonSand internal immutable _polygonSand;\n IERC20 internal immutable _fakePolygonSand;\n\n event SandClaimed(address indexed user, uint256 amount);\n\n constructor(IPolygonSand polygonSand, IERC20 fakePolygonSand) {\n _polygonSand = polygonSand;\n _fakePolygonSand = fakePolygonSand;\n }\n\n /**\n * @notice Swaps fake sand with the new polygonSand\n * @param amount the amount of tokens to be swapped\n */\n function claim(uint256 amount) external nonReentrant {\n require(unclaimedSand() >= amount, \"Not enough sand for claim\");\n bool success = _fakePolygonSand.transferFrom(msg.sender, address(this), amount);\n if (success) {\n _polygonSand.transfer(msg.sender, amount);\n emit SandClaimed(msg.sender, amount);\n }\n }\n\n // Getters\n\n /**\n * @notice Getter for amount of sand which is still locked in this contract\n */\n function unclaimedSand() public returns (uint256) {\n return _polygonSand.balanceOf(address(this));\n }\n\n /**\n * @notice Getter for amount of fake Sand swapped\n */\n function claimedSand() external view returns (uint256) {\n return _fakePolygonSand.balanceOf(address(this));\n }\n}\n" + }, + "src/solc_0.8/polygon/common/ERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/token/ERC1155/IERC1155Receiver.sol\";\n\nabstract contract ERC1155Receiver is IERC1155Receiver {\n function onERC1155Received(\n address, /* operator */\n address, /* from */\n uint256, /* id */\n uint256, /* value */\n bytes calldata /* data */\n ) external view virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(\n address, /* operator */\n address, /* from */\n uint256[] calldata, /* ids */\n uint256[] calldata, /* values */\n bytes calldata /* data */\n ) external view virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n" + }, + "src/solc_0.8/polygon/LiquidityMining/IRewardDistributionRecipient.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\n\nabstract contract IRewardDistributionRecipient is Ownable {\n address public rewardDistribution;\n\n function notifyRewardAmount(uint256 reward) external virtual;\n\n modifier onlyRewardDistribution() {\n require(_msgSender() == rewardDistribution, \"Caller is not reward distribution\");\n _;\n }\n\n modifier onlyRewardDistributionOrAccount(address account) {\n require(\n _msgSender() == rewardDistribution || _msgSender() == account,\n \"Caller is not reward distribution or account\"\n );\n _;\n }\n\n function setRewardDistribution(address _rewardDistribution) external onlyOwner {\n rewardDistribution = _rewardDistribution;\n }\n}\n" + }, + "src/solc_0.8/polygon/LiquidityMining/PolygonLandWeightedSANDRewardPool.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/utils/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts-0.8/utils/math/Math.sol\";\nimport \"@openzeppelin/contracts-0.8/security/ReentrancyGuard.sol\";\nimport \"@openzeppelin/contracts-0.8/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../common/Libraries/SafeMathWithRequire.sol\";\nimport \"./IRewardDistributionRecipient.sol\";\nimport \"../../common/interfaces/IERC721.sol\";\n\ncontract PolygonLPTokenWrapper {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 internal constant DECIMALS_18 = 1000000000000000000;\n\n IERC20 internal _stakeToken;\n\n uint256 private _totalSupply;\n mapping(address => uint256) private _balances;\n\n constructor(IERC20 stakeToken) {\n _stakeToken = stakeToken;\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account) public view returns (uint256) {\n return _balances[account];\n }\n\n function stake(uint256 amount) public virtual {\n _totalSupply = _totalSupply.add(amount);\n _balances[msg.sender] = _balances[msg.sender].add(amount);\n _stakeToken.safeTransferFrom(msg.sender, address(this), amount);\n }\n\n function withdraw(uint256 amount) public virtual {\n _totalSupply = _totalSupply.sub(amount);\n _balances[msg.sender] = _balances[msg.sender].sub(amount);\n _stakeToken.safeTransfer(msg.sender, amount);\n }\n}\n\n///@notice Reward Pool based on unipool contract : https://github.com/Synthetixio/Unipool/blob/master/contracts/Unipool.sol\n//with the addition of NFT multiplier reward\ncontract PolygonLandWeightedSANDRewardPool is PolygonLPTokenWrapper, IRewardDistributionRecipient, ReentrancyGuard {\n using SafeMath for uint256;\n using SafeMathWithRequire for uint256;\n using SafeERC20 for IERC20;\n using Address for address;\n\n event RewardAdded(uint256 reward);\n event Staked(address indexed user, uint256 amount);\n event Withdrawn(address indexed user, uint256 amount);\n event RewardPaid(address indexed user, uint256 reward);\n event MultiplierComputed(address indexed user, uint256 multiplier, uint256 contribution);\n\n uint256 public immutable duration;\n\n uint256 public periodFinish = 0;\n uint256 public rewardRate = 0;\n uint256 public lastUpdateTime;\n uint256 public rewardPerTokenStored;\n mapping(address => uint256) public userRewardPerTokenPaid;\n mapping(address => uint256) public rewards;\n\n uint256 internal constant DECIMALS_9 = 1000000000;\n uint256 internal constant MIDPOINT_9 = 500000000;\n uint256 internal constant NFT_FACTOR_6 = 10000;\n uint256 internal constant NFT_CONSTANT_3 = 9000;\n uint256 internal constant ROOT3_FACTOR = 697;\n\n IERC20 internal _rewardToken;\n IERC721 internal _multiplierNFToken;\n\n uint256 internal _totalContributions;\n mapping(address => uint256) internal _multipliers;\n mapping(address => uint256) internal _contributions;\n\n constructor(\n IERC20 stakeToken,\n IERC20 rewardToken,\n IERC721 multiplierNFToken,\n uint256 rewardDuration\n ) PolygonLPTokenWrapper(stakeToken) {\n _rewardToken = rewardToken;\n _multiplierNFToken = multiplierNFToken;\n duration = rewardDuration;\n }\n\n function totalContributions() public view returns (uint256) {\n return _totalContributions;\n }\n\n function contributionOf(address account) public view returns (uint256) {\n return _contributions[account];\n }\n\n function multiplierOf(address account) public view returns (uint256) {\n return _multipliers[account];\n }\n\n modifier updateReward(address account) {\n rewardPerTokenStored = rewardPerToken();\n\n if (block.timestamp >= periodFinish || _totalContributions != 0) {\n // ensure reward past the first staker do not get lost\n lastUpdateTime = lastTimeRewardApplicable();\n }\n if (account != address(0)) {\n rewards[account] = earned(account);\n userRewardPerTokenPaid[account] = rewardPerTokenStored;\n }\n _;\n }\n\n function lastTimeRewardApplicable() public view returns (uint256) {\n return Math.min(block.timestamp, periodFinish);\n }\n\n function rewardPerToken() public view returns (uint256) {\n if (totalContributions() == 0) {\n return rewardPerTokenStored;\n }\n return\n rewardPerTokenStored.add(\n lastTimeRewardApplicable().sub(lastUpdateTime).mul(rewardRate).mul(1e24).div(totalContributions())\n );\n }\n\n function earned(address account) public view returns (uint256) {\n return\n contributionOf(account).mul(rewardPerToken().sub(userRewardPerTokenPaid[account])).div(1e24).add(\n rewards[account]\n );\n }\n\n function computeContribution(uint256 amountStaked, uint256 numLands) public pure returns (uint256) {\n if (numLands == 0) {\n return amountStaked;\n }\n uint256 nftContrib = NFT_FACTOR_6.mul(NFT_CONSTANT_3.add(numLands.sub(1).mul(ROOT3_FACTOR).add(1).cbrt3()));\n if (nftContrib > MIDPOINT_9) {\n nftContrib = MIDPOINT_9.add(nftContrib.sub(MIDPOINT_9).div(10));\n }\n return amountStaked.add(amountStaked.mul(nftContrib).div(DECIMALS_9));\n }\n\n function updateContribution(address account) internal {\n _totalContributions = _totalContributions.sub(contributionOf(account));\n _multipliers[account] = _multiplierNFToken.balanceOf(account);\n\n uint256 contribution = computeContribution(balanceOf(account), multiplierOf(account));\n\n _totalContributions = _totalContributions.add(contribution);\n _contributions[account] = contribution;\n }\n\n function computeMultiplier(address account) public onlyRewardDistributionOrAccount(account) updateReward(account) {\n updateContribution(account);\n\n emit MultiplierComputed(account, multiplierOf(account), contributionOf(account));\n }\n\n function stake(uint256 amount) public override nonReentrant updateReward(msg.sender) {\n require(amount > 0, \"Cannot stake 0\");\n\n super.stake(amount);\n\n updateContribution(msg.sender);\n\n emit Staked(msg.sender, amount);\n }\n\n function withdraw(uint256 amount) public override nonReentrant updateReward(msg.sender) {\n require(amount > 0, \"Cannot withdraw 0\");\n\n super.withdraw(amount);\n\n updateContribution(msg.sender);\n\n emit Withdrawn(msg.sender, amount);\n }\n\n function exit() external {\n withdraw(balanceOf(msg.sender));\n getReward();\n }\n\n function getReward() public nonReentrant updateReward(msg.sender) {\n uint256 reward = rewards[msg.sender];\n if (reward > 0) {\n rewards[msg.sender] = 0;\n _rewardToken.safeTransfer(msg.sender, reward);\n emit RewardPaid(msg.sender, reward);\n }\n }\n\n ///@notice to be called after the amount of reward tokens (specified by the reward parameter) has been sent to the contract\n // Note that the reward should be divisible by the duration to avoid reward token lost\n ///@param reward number of token to be distributed over the duration\n function notifyRewardAmount(uint256 reward) external override onlyRewardDistribution updateReward(address(0)) {\n if (block.timestamp >= periodFinish) {\n rewardRate = reward.div(duration);\n } else {\n uint256 remaining = periodFinish.sub(block.timestamp);\n uint256 leftover = remaining.mul(rewardRate);\n rewardRate = reward.add(leftover).div(duration);\n }\n lastUpdateTime = block.timestamp;\n periodFinish = block.timestamp.add(duration);\n emit RewardAdded(reward);\n }\n\n // Add Setter functions for every external contract\n\n function SetRewardToken(address newRewardToken) external onlyOwner {\n require(newRewardToken.isContract(), \"Bad RewardToken address\");\n\n _rewardToken = IERC20(newRewardToken);\n }\n\n function SetStakeLPToken(address newStakeLPToken) external onlyOwner {\n require(newStakeLPToken.isContract(), \"Bad StakeToken address\");\n\n _stakeToken = IERC20(newStakeLPToken);\n }\n\n function SetNFTMultiplierToken(address newNFTMultiplierToken) external onlyOwner {\n require(newNFTMultiplierToken.isContract(), \"Bad NFTMultiplierToken address\");\n\n _multiplierNFToken = IERC721(newNFTMultiplierToken);\n }\n}\n" + }, + "src/solc_0.8/polygon/LiquidityMining/PolygonSANDRewardPool.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/utils/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts-0.8/utils/math/Math.sol\";\nimport \"@openzeppelin/contracts-0.8/token/ERC20/utils/SafeERC20.sol\";\nimport \"./IRewardDistributionRecipient.sol\";\nimport \"../../common/interfaces/IERC721.sol\";\n\ncontract LPTokenWrapper {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n IERC20 internal _stakeToken;\n\n uint256 private _totalSupply;\n mapping(address => uint256) private _balances;\n\n constructor(IERC20 stakeToken) {\n _stakeToken = stakeToken;\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account) public view returns (uint256) {\n return _balances[account];\n }\n\n function stake(uint256 amount) public virtual {\n _totalSupply = _totalSupply.add(amount);\n _balances[msg.sender] = _balances[msg.sender].add(amount);\n _stakeToken.safeTransferFrom(msg.sender, address(this), amount);\n }\n\n function withdraw(uint256 amount) public virtual {\n _totalSupply = _totalSupply.sub(amount);\n _balances[msg.sender] = _balances[msg.sender].sub(amount);\n _stakeToken.safeTransfer(msg.sender, amount);\n }\n}\n\ncontract PolygonSANDRewardPool is LPTokenWrapper, IRewardDistributionRecipient {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 public constant DURATION = 30 days; // Reward period\n\n uint256 public periodFinish = 0;\n uint256 public rewardRate = 0;\n uint256 public lastUpdateTime;\n uint256 public rewardPerTokenStored;\n mapping(address => uint256) public userRewardPerTokenPaid;\n mapping(address => uint256) public rewards;\n\n event RewardAdded(uint256 reward);\n event Staked(address indexed user, uint256 amount);\n event Withdrawn(address indexed user, uint256 amount);\n event RewardPaid(address indexed user, uint256 reward);\n\n IERC20 internal _rewardToken;\n\n constructor(IERC20 stakeToken, IERC20 rewardToken) LPTokenWrapper(stakeToken) {\n _rewardToken = rewardToken;\n }\n\n modifier updateReward(address account) {\n rewardPerTokenStored = rewardPerToken();\n lastUpdateTime = lastTimeRewardApplicable();\n if (account != address(0)) {\n rewards[account] = earned(account);\n userRewardPerTokenPaid[account] = rewardPerTokenStored;\n }\n _;\n }\n\n function lastTimeRewardApplicable() public view returns (uint256) {\n return Math.min(block.timestamp, periodFinish);\n }\n\n function rewardPerToken() public view returns (uint256) {\n if (totalSupply() == 0) {\n return rewardPerTokenStored;\n }\n return\n rewardPerTokenStored.add(\n lastTimeRewardApplicable().sub(lastUpdateTime).mul(rewardRate).mul(1e18).div(totalSupply())\n );\n }\n\n function earned(address account) public view returns (uint256) {\n return\n balanceOf(account).mul(rewardPerToken().sub(userRewardPerTokenPaid[account])).div(1e18).add(\n rewards[account]\n );\n }\n\n // stake visibility is public as overriding LPTokenWrapper's stake() function\n function stake(uint256 amount) public override updateReward(msg.sender) {\n require(amount > 0, \"Cannot stake 0\");\n super.stake(amount);\n emit Staked(msg.sender, amount);\n }\n\n function withdraw(uint256 amount) public override updateReward(msg.sender) {\n require(amount > 0, \"Cannot withdraw 0\");\n super.withdraw(amount);\n emit Withdrawn(msg.sender, amount);\n }\n\n function exit() external {\n withdraw(balanceOf(msg.sender));\n getReward();\n }\n\n function getReward() public updateReward(msg.sender) {\n uint256 reward = earned(msg.sender);\n if (reward > 0) {\n rewards[msg.sender] = 0;\n _rewardToken.safeTransfer(msg.sender, reward);\n emit RewardPaid(msg.sender, reward);\n }\n }\n\n function notifyRewardAmount(uint256 reward) external override onlyRewardDistribution updateReward(address(0)) {\n if (block.timestamp >= periodFinish) {\n rewardRate = reward.div(DURATION);\n } else {\n uint256 remaining = periodFinish.sub(block.timestamp);\n uint256 leftover = remaining.mul(rewardRate);\n rewardRate = reward.add(leftover).div(DURATION);\n }\n lastUpdateTime = block.timestamp;\n periodFinish = block.timestamp.add(DURATION);\n emit RewardAdded(reward);\n }\n\n // Add Setter functions for every external contract\n\n function SetRewardLPToken(address newRewardToken) external onlyOwner {\n require(newRewardToken != address(0), \"Bad RewardToken address\");\n\n _rewardToken = IERC20(newRewardToken);\n }\n\n function SetStakeLPToken(address newStakeLPToken) external onlyOwner {\n require(newStakeLPToken != address(0), \"Bad StakeToken address\");\n\n _stakeToken = IERC20(newStakeLPToken);\n }\n}\n" + }, + "src/solc_0.8/polygon/root/IRootChainManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\ninterface IRootChainManager {\n event TokenMapped(address indexed rootToken, address indexed childToken, bytes32 indexed tokenType);\n\n event PredicateRegistered(bytes32 indexed tokenType, address indexed predicateAddress);\n\n function registerPredicate(bytes32 tokenType, address predicateAddress) external;\n\n function mapToken(\n address rootToken,\n address childToken,\n bytes32 tokenType\n ) external;\n\n function cleanMapToken(address rootToken, address childToken) external;\n\n function remapToken(\n address rootToken,\n address childToken,\n bytes32 tokenType\n ) external;\n\n function depositEtherFor(address user) external payable;\n\n function depositFor(\n address user,\n address rootToken,\n bytes calldata depositData\n ) external;\n\n function exit(bytes calldata inputData) external;\n}\n" + }, + "src/solc_0.8/polygon/root/land/LandTunnel.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"fx-portal/contracts/tunnel/FxBaseRootTunnel.sol\";\nimport \"../../../common/interfaces/ILandToken.sol\";\nimport \"../../../common/interfaces/IERC721MandatoryTokenReceiver.sol\";\nimport \"../../../common/BaseWithStorage/ERC2771Handler.sol\";\nimport \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\nimport \"@openzeppelin/contracts-0.8/security/Pausable.sol\";\n\n/// @title LAND bridge on L1\ncontract LandTunnel is FxBaseRootTunnel, IERC721MandatoryTokenReceiver, ERC2771Handler, Ownable, Pausable {\n address public immutable rootToken;\n bool internal transferringToL2;\n\n event Deposit(address indexed user, uint256 size, uint256 x, uint256 y, bytes data);\n event Withdraw(address indexed user, uint256 size, uint256 x, uint256 y, bytes data);\n\n constructor(\n address _checkpointManager,\n address _fxRoot,\n address _rootToken,\n address _trustedForwarder\n ) FxBaseRootTunnel(_checkpointManager, _fxRoot) {\n rootToken = _rootToken;\n __ERC2771Handler_initialize(_trustedForwarder);\n }\n\n function onERC721Received(\n address, /* operator */\n address, /* from */\n uint256, /* tokenId */\n bytes calldata /* data */\n ) external view override returns (bytes4) {\n require(transferringToL2, \"LandTunnel: !BRIDGING\");\n return this.onERC721Received.selector;\n }\n\n function onERC721BatchReceived(\n address, /* operator */\n address, /* from */\n uint256[] calldata, /* ids */\n bytes calldata /* data */\n ) external view override returns (bytes4) {\n require(transferringToL2, \"LandTunnel: !BRIDGING\");\n return this.onERC721BatchReceived.selector;\n }\n\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return interfaceId == 0x5e8bf644 || interfaceId == 0x01ffc9a7;\n }\n\n function batchTransferQuadToL2(\n address to,\n uint256[] memory sizes,\n uint256[] memory xs,\n uint256[] memory ys,\n bytes memory data\n ) public whenNotPaused() {\n require(sizes.length == xs.length && xs.length == ys.length, \"l2: invalid data\");\n transferringToL2 = true;\n ILandToken(rootToken).batchTransferQuad(_msgSender(), address(this), sizes, xs, ys, data);\n transferringToL2 = false;\n for (uint256 index = 0; index < sizes.length; index++) {\n bytes memory message = abi.encode(to, sizes[index], xs[index], ys[index], data);\n _sendMessageToChild(message);\n emit Deposit(to, sizes[index], xs[index], ys[index], data);\n }\n }\n\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyOwner {\n _trustedForwarder = trustedForwarder;\n }\n\n /// @dev Pauses all token transfers across bridge\n function pause() external onlyOwner {\n _pause();\n }\n\n /// @dev Unpauses all token transfers across bridge\n function unpause() external onlyOwner {\n _unpause();\n }\n\n function _processMessageFromChild(bytes memory message) internal override {\n (address to, uint256[] memory size, uint256[] memory x, uint256[] memory y, bytes memory data) =\n abi.decode(message, (address, uint256[], uint256[], uint256[], bytes));\n for (uint256 index = 0; index < x.length; index++) {\n ILandToken(rootToken).transferQuad(address(this), to, size[index], x[index], y[index], data);\n emit Withdraw(to, size[index], x[index], y[index], data);\n }\n }\n\n function _msgSender() internal view override(Context, ERC2771Handler) returns (address sender) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view override(Context, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n}\n" + }, + "src/solc_0.8/polygon/root/land/LandTunnelMigration.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {ILandToken} from \"../../../common/interfaces/ILandToken.sol\";\n\n/// @title Tunnel migration on L1\n/// @author The Sandbox\n/// @notice Contract handling the migration of LAND tokens from a tunnel to a new one\ncontract LandTunnelMigration {\n ILandToken public immutable landToken;\n address public immutable newLandTunnel;\n address public immutable oldLandTunnel;\n address private admin;\n\n event TunnelLandsMigrated(address indexed oldLandTunnel, address indexed newLandTunnel, uint256[] ids);\n event TunnelQuadsMigrated(\n address indexed oldLandTunnel,\n address indexed newLandTunnel,\n uint256[] sizes,\n uint256[] x,\n uint256[] y\n );\n event AdminChanged(address indexed _newAdmin);\n\n modifier isAdmin() {\n require(admin == msg.sender, \"LandTunnelMigration: !AUTHORISED\");\n _;\n }\n\n /// @notice Constructor of the tunnel migration contract\n /// @param _landToken LAND token address\n /// @param _newLandTunnel the tunnel address to migrate to\n /// @param _oldLandTunnel the tunnel address to migrate from\n /// @param _admin admin of the contract\n constructor(\n address _landToken,\n address _newLandTunnel,\n address _oldLandTunnel,\n address _admin\n ) {\n require(_admin != address(0), \"LandTunnelMigration: admin can't be zero address\");\n require(_landToken != address(0), \"LandTunnelMigration: landToken can't be zero address\");\n require(_newLandTunnel != address(0), \"LandTunnelMigration: new Tunnel can't be zero address\");\n require(_oldLandTunnel != address(0), \"LandTunnelMigration: old Tunnel can't be zero address\");\n\n admin = _admin;\n landToken = ILandToken(_landToken);\n newLandTunnel = _newLandTunnel;\n oldLandTunnel = _oldLandTunnel;\n\n emit AdminChanged(_admin);\n }\n\n /// @dev Transfers all the passed land ids from the old land tunnel to the new land tunnel\n /// @notice This method needs super operator role to execute\n /// @param ids of land tokens to be migrated\n function migrateLandsToTunnel(uint256[] memory ids) external isAdmin {\n landToken.batchTransferFrom(oldLandTunnel, newLandTunnel, ids, \"\");\n emit TunnelLandsMigrated(oldLandTunnel, newLandTunnel, ids);\n }\n\n /// @dev Transfers all the passed quads from the old land tunnel to the new land tunnel\n /// @notice This method needs super operator role to execute\n /// @param sizes of land quads to be migrated\n /// @param x coordinate of land quads to be migrated\n /// @param y coordinate of land quads to be migrated\n function migrateQuadsToTunnel(\n uint256[] memory sizes,\n uint256[] memory x,\n uint256[] memory y\n ) external isAdmin {\n landToken.batchTransferQuad(oldLandTunnel, newLandTunnel, sizes, x, y, \"\");\n emit TunnelQuadsMigrated(oldLandTunnel, newLandTunnel, sizes, x, y);\n }\n\n /// @notice changes admin to new admin\n /// @param _newAdmin the new admin to be set\n function changeAdmin(address _newAdmin) external isAdmin {\n require(_newAdmin != address(0), \"LandTunnelMigration: admin can't be zero address\");\n admin = _newAdmin;\n emit AdminChanged(_newAdmin);\n }\n}\n" + }, + "src/solc_0.8/polygon/root/land/LandTunnelV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {\n OwnableUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {FxBaseRootTunnelUpgradeable} from \"../../../common/fx-portal/FxBaseRootTunnelUpgradeable.sol\";\nimport {ERC2771Handler} from \"../../../common/BaseWithStorage/ERC2771Handler.sol\";\nimport {ILandTokenV2} from \"../../../common/interfaces/ILandTokenV2.sol\";\nimport {IERC721MandatoryTokenReceiver} from \"../../../common/interfaces/IERC721MandatoryTokenReceiver.sol\";\n\n/// @title LandTunnelV2\n/// @author The Sandbox\n/// @notice LAND tunnel on the root chain\ncontract LandTunnelV2 is\n FxBaseRootTunnelUpgradeable,\n IERC721MandatoryTokenReceiver,\n ERC2771Handler,\n OwnableUpgradeable,\n PausableUpgradeable\n{\n ILandTokenV2 public rootToken;\n bool internal transferringToL2;\n\n event Deposit(address indexed user, uint256 size, uint256 x, uint256 y, bytes data);\n event Withdraw(address indexed user, uint256 size, uint256 x, uint256 y, bytes data);\n\n /// @notice Initializes the contract\n /// @param _checkpointManager checkpoint manager address\n /// @param _fxRoot state sender contract\n /// @param _rootToken LAND token on the root chain\n /// @param _trustedForwarder trusted forwarder for meta-tx\n function initialize(\n address _checkpointManager,\n address _fxRoot,\n ILandTokenV2 _rootToken,\n address _trustedForwarder\n ) public initializer {\n rootToken = _rootToken;\n __Ownable_init();\n __Pausable_init();\n __FxBaseRootTunnelUpgradeable_initialize(_checkpointManager, _fxRoot);\n __ERC2771Handler_initialize(_trustedForwarder);\n }\n\n /// @dev called on ERC721 transfer to this contract\n /// @param operator address of the one sending the ERC721 Token\n /// @return onERC721Received function selector\n function onERC721Received(\n address operator,\n address, /* from */\n uint256, /* tokenId */\n bytes calldata /* data */\n ) external view override returns (bytes4) {\n require(transferringToL2 || rootToken.isSuperOperator(operator), \"LandTunnelV2: !BRIDGING\");\n return this.onERC721Received.selector;\n }\n\n /// @dev called on ERC721 batch transfer to this contract\n /// @param operator address of the one sending the ERC721 Token\n /// @return onERC721BatchReceived function selector\n function onERC721BatchReceived(\n address operator,\n address, /* from */\n uint256[] calldata, /* ids */\n bytes calldata /* data */\n ) external view override returns (bytes4) {\n require(transferringToL2 || rootToken.isSuperOperator(operator), \"LandTunnelV2: !BRIDGING\");\n return this.onERC721BatchReceived.selector;\n }\n\n /// @dev to be called by external contact to check if this contract supports ERC721 token and batch token receive\n /// @param interfaceId the interface to be checked if supported by the contract\n /// @return 0x5e8bf644 is the interface of IERC721MandatoryTokenReceiver and 0x01ffc9a7 for the Eip 165 supports interface's interface id\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return interfaceId == 0x5e8bf644 || interfaceId == 0x01ffc9a7;\n }\n\n /// @notice Send a batch of quads to L2\n /// @param to address of the receiver on L2\n /// @param sizes sizes of quad\n /// @param xs x coordinates of quads\n /// @param ys y coordinates of quads\n /// @param data data send to the receiver onERC721BatchReceived on L1\n function batchTransferQuadToL2(\n address to,\n uint256[] memory sizes,\n uint256[] memory xs,\n uint256[] memory ys,\n bytes memory data\n ) external whenNotPaused() {\n require(to != address(0), \"LandTunnelV2: can't send to zero address\");\n require(sizes.length == xs.length, \"LandTunnelV2: sizes's and x's length are different\");\n require(xs.length == ys.length, \"LandTunnelV2: x's and y's length are different\");\n transferringToL2 = true;\n rootToken.batchTransferQuad(_msgSender(), address(this), sizes, xs, ys, data);\n transferringToL2 = false;\n for (uint256 index = 0; index < sizes.length; index++) {\n bytes memory message = abi.encode(to, sizes[index], xs[index], ys[index], data);\n _sendMessageToChild(message);\n emit Deposit(to, sizes[index], xs[index], ys[index], data);\n }\n }\n\n /// @notice sets the fx-child tunnel\n /// @dev only owner can call this funtion\n /// @param _fxChildTunnel address of the fx-child tunnel\n function setFxChildTunnel(address _fxChildTunnel) public override onlyOwner {\n super.setFxChildTunnel(_fxChildTunnel);\n }\n\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyOwner {\n _trustedForwarder = trustedForwarder;\n\n emit TrustedForwarderSet(trustedForwarder);\n }\n\n /// @dev Pauses all token transfers across bridge\n function pause() external onlyOwner {\n _pause();\n }\n\n /// @dev Unpauses all token transfers across bridge\n function unpause() external onlyOwner {\n _unpause();\n }\n\n function _processMessageFromChild(bytes memory message) internal override {\n (address to, uint256[] memory size, uint256[] memory x, uint256[] memory y, bytes memory data) =\n abi.decode(message, (address, uint256[], uint256[], uint256[], bytes));\n for (uint256 index = 0; index < x.length; index++) {\n rootToken.mintAndTransferQuad(to, size[index], x[index], y[index], data);\n emit Withdraw(to, size[index], x[index], y[index], data);\n }\n }\n\n function _msgSender() internal view override(ContextUpgradeable, ERC2771Handler) returns (address) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n\n uint256[50] private __gap;\n}\n" + }, + "src/solc_0.8/polygon/root/land/MockLandTunnel.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"./LandTunnel.sol\";\n\ncontract MockLandTunnel is LandTunnel {\n constructor(\n address _checkpointManager,\n address _fxRoot,\n address _rootToken,\n address _trustedForwarder\n ) LandTunnel(_checkpointManager, _fxRoot, _rootToken, _trustedForwarder) {\n checkpointManager = ICheckpointManager(_checkpointManager);\n fxRoot = IFxStateSender(_fxRoot);\n }\n\n function receiveMessage(bytes memory message) public virtual override {\n _processMessageFromChild(message);\n }\n}\n" + }, + "src/solc_0.8/polygon/root/land/MockLandTunnelV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"./LandTunnelV2.sol\";\n\ncontract MockLandTunnelV2 is LandTunnelV2 {\n function receiveMessage(bytes memory inputData) public override {\n _processMessageFromChild(inputData);\n }\n}\n" + }, + "src/solc_0.8/polygon/root/SandPolygonDepositor.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\nimport \"../../common/interfaces/IERC20Extended.sol\";\nimport \"./IRootChainManager.sol\";\n\ncontract SandPolygonDepositor {\n IERC20Extended internal immutable _sand;\n address internal immutable _predicate;\n IRootChainManager internal immutable _rootChainManager;\n\n constructor(\n IERC20Extended sand,\n address predicate,\n IRootChainManager rootChainManager\n ) {\n _sand = sand;\n _predicate = predicate;\n _rootChainManager = rootChainManager;\n }\n\n function depositToPolygon(address beneficiary, uint256 amount) public {\n _sand.transferFrom(beneficiary, address(this), amount);\n _sand.approve(_predicate, amount);\n _rootChainManager.depositFor(beneficiary, address(_sand), abi.encode(amount));\n }\n}\n" + }, + "src/solc_0.8/raffle/CareBears.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"./GenericRaffle.sol\";\n\n/* solhint-disable max-states-count */\ncontract CareBears is GenericRaffle {\n uint256 public constant MAX_SUPPLY = 3_060;\n\n function initialize(\n string memory baseURI,\n string memory _name,\n string memory _symbol,\n address payable _sandOwner,\n address _signAddress,\n address _trustedForwarder\n ) public initializer {\n __GenericRaffle_init(baseURI, _name, _symbol, _sandOwner, _signAddress, _trustedForwarder, MAX_SUPPLY);\n }\n}\n" + }, + "src/solc_0.8/raffle/GenericRaffle.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {ERC2771HandlerUpgradeable} from \"../common/BaseWithStorage/ERC2771/ERC2771HandlerUpgradeable.sol\";\n\nimport {Address} from \"@openzeppelin/contracts-0.8/utils/Address.sol\";\nimport \"@openzeppelin/contracts-0.8/token/ERC1155/IERC1155.sol\";\nimport \"@openzeppelin/contracts-0.8/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts-0.8/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts-0.8/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts-0.8/utils/cryptography/ECDSA.sol\";\nimport \"@openzeppelin/contracts-0.8/security/ReentrancyGuard.sol\";\n\nimport {ContextUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol\";\n\n/* solhint-disable max-states-count */\ncontract GenericRaffle is\n ERC721EnumerableUpgradeable,\n OwnableUpgradeable,\n ReentrancyGuardUpgradeable,\n ERC2771HandlerUpgradeable\n{\n using Address for address;\n uint256 public maxSupply;\n\n event TogglePaused(bool _pause);\n event Personalized(uint256 _tokenId, uint256 _personalizationMask);\n event ContractInitialized(\n string baseURI,\n string _name,\n string _symbol,\n address _sandOwner,\n address _signAddress,\n uint256 _maxSupply\n );\n event WaveSetup(\n uint256 _waveType,\n uint256 _waveMaxTokens,\n uint256 _waveMaxTokensToBuy,\n uint256 _waveSingleTokenPrice\n );\n event AllowedExecuteMintSet(address _address);\n event SandOwnerSet(address _owner);\n event BaseURISet(string baseURI);\n event SignAddressSet(address _signAddress);\n\n uint256 public waveType = 0;\n uint256 public waveMaxTokens;\n uint256 public waveMaxTokensToBuy;\n uint256 public waveSingleTokenPrice;\n uint256 public waveTotalMinted;\n\n uint256 public erc1155Id;\n address public contractAddress;\n\n mapping(address => mapping(uint256 => uint256)) public waveOwnerToClaimedCounts;\n mapping(uint256 => uint256) public personalizationTraits; // stores the personalization for a tokenId\n uint256 public indexWave;\n uint256 public paused;\n\n mapping(uint256 => uint256) private signatureIds;\n mapping(uint256 => uint256) private availableIds;\n\n address public allowedToExecuteMint;\n address public sandOwner;\n address public signAddress;\n string public baseTokenURI;\n\n function __GenericRaffle_init(\n string memory baseURI,\n string memory _name,\n string memory _symbol,\n address payable _sandOwner,\n address _signAddress,\n address _trustedForwarder,\n uint256 _maxSupply\n ) internal onlyInitializing {\n __ERC721_init(_name, _symbol);\n __ERC2771Handler_initialize(_trustedForwarder);\n __Ownable_init_unchained();\n __ReentrancyGuard_init();\n setBaseURI(baseURI);\n require(bytes(baseURI).length != 0, \"baseURI is not set\");\n require(bytes(_name).length != 0, \"_name is not set\");\n require(bytes(_symbol).length != 0, \"_symbol is not set\");\n require(_signAddress != address(0x0), \"Sign address is zero address\");\n require(_trustedForwarder != address(0x0), \"Trusted forwarder is zero address\");\n require(_sandOwner != address(0x0), \"Sand owner is zero address\");\n require(_maxSupply > 0, \"Max supply should be more than 0\");\n sandOwner = _sandOwner;\n signAddress = _signAddress;\n maxSupply = _maxSupply;\n\n emit ContractInitialized(baseURI, _name, _symbol, _sandOwner, _signAddress, _maxSupply);\n }\n\n function setupWave(\n uint256 _waveType,\n uint256 _waveMaxTokens,\n uint256 _waveMaxTokensToBuy,\n uint256 _waveSingleTokenPrice,\n address _contractAddress,\n uint256 _erc1155Id\n ) external onlyOwner {\n require(_waveMaxTokens <= maxSupply, \"_waveMaxTokens should not exceed maxSupply\");\n require(_waveType < 3 && _waveMaxTokens > 0 && _waveMaxTokensToBuy > 0, \"Invalid configuration\");\n if (_waveType != 0) {\n require(_contractAddress != address(0x0), \"Invalid contract address\");\n require(_contractAddress.isContract(), \"Contract address must be that of a contract\");\n }\n require(_waveMaxTokensToBuy <= _waveMaxTokens, \"Invalid supply configuration\");\n\n waveType = _waveType;\n waveMaxTokens = _waveMaxTokens;\n waveMaxTokensToBuy = _waveMaxTokensToBuy;\n waveSingleTokenPrice = _waveSingleTokenPrice;\n waveTotalMinted = 0;\n contractAddress = _waveType == 0 ? address(0x0) : _contractAddress;\n erc1155Id = _waveType == 2 ? _erc1155Id : 0;\n indexWave++;\n\n emit WaveSetup(_waveType, _waveMaxTokens, _waveMaxTokensToBuy, _waveSingleTokenPrice);\n }\n\n function price(uint256 _count) public view virtual returns (uint256) {\n return waveSingleTokenPrice * _count;\n }\n\n function chain() public view returns (uint256) {\n return block.chainid;\n }\n\n function checkWaveNotComplete(uint256 _amount) internal view returns (bool) {\n return _amount > 0 && waveTotalMinted + _amount <= waveMaxTokens;\n }\n\n function checkLimitNotReached(address _wallet, uint256 _amount) internal view returns (bool) {\n return\n waveOwnerToClaimedCounts[_wallet][indexWave - 1] + _amount <= waveMaxTokensToBuy &&\n totalSupply() + _amount <= maxSupply;\n }\n\n function checkMintAllowed(address _wallet, uint256 _amount) public view returns (bool) {\n return checkWaveNotComplete(_amount) && checkLimitNotReached(_wallet, _amount);\n }\n\n function mint(\n address _wallet,\n uint256 _amount,\n uint256 _signatureId,\n bytes memory _signature\n ) external nonReentrant {\n require(indexWave > 0, \"Contract is not configured\");\n require(_msgSender() == allowedToExecuteMint, \"Not allowed\");\n require(paused == 0, \"Contract is paused\");\n require(_wallet != address(0x0), \"Wallet is zero address\");\n require(_amount > 0, \"Amount cannot be 0\");\n require(signatureIds[_signatureId] == 0, \"signatureId already used\");\n require(\n checkSignature(_wallet, _signatureId, address(this), block.chainid, _signature) == signAddress,\n \"Signature failed\"\n );\n\n signatureIds[_signatureId] = 1;\n\n require(checkWaveNotComplete(_amount), \"Wave completed\");\n require(checkLimitNotReached(_wallet, _amount), \"Max allowed\");\n\n if (waveType == 1) {\n require(IERC721(contractAddress).balanceOf(_wallet) > 0, \"No NFT\");\n } else if (waveType == 2) {\n require(IERC1155(contractAddress).balanceOf(_wallet, erc1155Id) > 0, \"No NFT\");\n }\n\n uint256 _price = price(_amount);\n if (_price > 0) {\n SafeERC20.safeTransferFrom(IERC20(_msgSender()), _wallet, sandOwner, _price);\n }\n\n waveOwnerToClaimedCounts[_wallet][indexWave - 1] += _amount;\n\n waveTotalMinted += _amount;\n\n for (uint256 i = 0; i < _amount; i++) {\n uint256 tokenId = getRandomToken(_wallet, totalSupply());\n _safeMint(_wallet, tokenId);\n }\n }\n\n function checkSignature(\n address _wallet,\n uint256 _signatureId,\n address _contractAddress,\n uint256 _chainId,\n bytes memory _signature\n ) public pure returns (address) {\n return\n ECDSA.recover(\n keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(abi.encode(_wallet, _signatureId, _contractAddress, _chainId))\n )\n ),\n _signature\n );\n }\n\n function checkPersonalizationSignature(\n address _wallet,\n uint256 _signatureId,\n address _contractAddress,\n uint256 _chainId,\n uint256 _tokenId,\n uint256 _personalizationMask,\n bytes memory _signature\n ) public pure returns (address) {\n return\n ECDSA.recover(\n keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _wallet,\n _signatureId,\n _contractAddress,\n _chainId,\n _tokenId,\n _personalizationMask\n )\n )\n )\n ),\n _signature\n );\n }\n\n // Thx Cyberkongs VX <3\n function getRandomToken(address _wallet, uint256 _totalMinted) private returns (uint256) {\n uint256 remaining = maxSupply - _totalMinted;\n uint256 rand =\n uint256(keccak256(abi.encodePacked(_wallet, block.difficulty, block.timestamp, remaining))) % remaining;\n uint256 value = rand;\n\n if (availableIds[rand] != 0) {\n value = availableIds[rand];\n }\n\n if (availableIds[remaining - 1] == 0) {\n availableIds[rand] = remaining - 1;\n } else {\n availableIds[rand] = availableIds[remaining - 1];\n }\n\n return value;\n }\n\n function personalizationOf(uint256 _tokenId) external view returns (uint256) {\n return personalizationTraits[_tokenId];\n }\n\n function toggleSale() external onlyOwner {\n paused = paused == 0 ? 1 : 0;\n emit TogglePaused(paused == 1);\n }\n\n function personalize(\n uint256 _signatureId,\n bytes memory _signature,\n uint256 _tokenId,\n uint256 _personalizationMask\n ) external {\n require(ownerOf(_tokenId) == _msgSender(), \"You must be the owner of the token in order to personalize it\");\n\n require(signatureIds[_signatureId] == 0, \"SignatureId already used\");\n require(\n checkPersonalizationSignature(\n _msgSender(),\n _signatureId,\n address(this),\n block.chainid,\n _tokenId,\n _personalizationMask,\n _signature\n ) == signAddress,\n \"Signature failed\"\n );\n\n signatureIds[_signatureId] = 1;\n\n personalizationTraits[_tokenId] = _personalizationMask;\n emit Personalized(_tokenId, _personalizationMask);\n }\n\n function setAllowedExecuteMint(address _address) external onlyOwner {\n require(_address != address(0x0), \"Address is zero address\");\n allowedToExecuteMint = _address;\n emit AllowedExecuteMintSet(_address);\n }\n\n function setSandOwnerAddress(address _owner) external onlyOwner {\n require(_owner != address(0x0), \"Owner is zero address\");\n sandOwner = _owner;\n emit SandOwnerSet(_owner);\n }\n\n function _baseURI() internal view virtual override returns (string memory) {\n return baseTokenURI;\n }\n\n function setBaseURI(string memory baseURI) public onlyOwner {\n require(bytes(baseURI).length != 0, \"baseURI is not set\");\n baseTokenURI = baseURI;\n emit BaseURISet(baseURI);\n }\n\n function setSignAddress(address _signAddress) external onlyOwner {\n require(_signAddress != address(0x0), \"Sign address is zero address\");\n signAddress = _signAddress;\n emit SignAddressSet(_signAddress);\n }\n\n function _msgSender()\n internal\n view\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (address sender)\n {\n return ERC2771HandlerUpgradeable._msgSender();\n }\n\n function _msgData() internal view override(ContextUpgradeable, ERC2771HandlerUpgradeable) returns (bytes calldata) {\n return ERC2771HandlerUpgradeable._msgData();\n }\n\n function renounceOwnership() public virtual override onlyOwner {\n revert(\"Renounce ownership is not available\");\n }\n\n // Empty storage space in contracts for future enhancements\n // ref: https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/issues/13)\n uint256[50] private __gap;\n}\n" + }, + "src/solc_0.8/raffle/PeopleOfCryptoGeneric.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./GenericRaffle.sol\";\n\n/* solhint-disable max-states-count */\ncontract PeopleOfCryptoGeneric is GenericRaffle {\n uint256 public constant MAX_SUPPLY = 8_430;\n\n function initialize(\n string memory baseURI,\n string memory _name,\n string memory _symbol,\n address payable _sandOwner,\n address _signAddress,\n address _trustedForwarder\n ) public initializer {\n __GenericRaffle_init(baseURI, _name, _symbol, _sandOwner, _signAddress, _trustedForwarder, MAX_SUPPLY);\n }\n}\n" + }, + "src/solc_0.8/raffle/PlayboyPartyPeople.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.2;\n\nimport \"./GenericRaffle.sol\";\n\n/* solhint-disable max-states-count */\ncontract PlayboyPartyPeople is GenericRaffle {\n uint256 public constant MAX_SUPPLY = 1_969;\n\n function initialize(\n string memory baseURI,\n string memory _name,\n string memory _symbol,\n address payable _sandOwner,\n address _signAddress,\n address _trustedForwarder\n ) public initializer {\n __GenericRaffle_init(baseURI, _name, _symbol, _sandOwner, _signAddress, _trustedForwarder, MAX_SUPPLY);\n }\n}\n" + }, + "src/solc_0.8/raffle/SteveAoki.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./GenericRaffle.sol\";\n\n/* solhint-disable max-states-count */\ncontract SteveAoki is GenericRaffle {\n uint256 public constant MAX_SUPPLY = 3_333;\n\n function initialize(\n string memory baseURI,\n string memory _name,\n string memory _symbol,\n address payable _sandOwner,\n address _signAddress,\n address _trustedForwarder\n ) public initializer {\n __GenericRaffle_init(baseURI, _name, _symbol, _sandOwner, _signAddress, _trustedForwarder, MAX_SUPPLY);\n }\n}\n" + }, + "src/solc_0.8/Sand/SandBaseToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport \"../common/BaseWithStorage/ERC20/extensions/ERC20BasicApproveExtension.sol\";\nimport \"../common/BaseWithStorage/ERC20/ERC20BaseToken.sol\";\n\ncontract SandBaseToken is ERC20BaseToken, ERC20BasicApproveExtension {\n constructor(\n address sandAdmin,\n address executionAdmin,\n address beneficiary,\n uint256 amount\n ) ERC20BaseToken(\"SAND\", \"SAND\", sandAdmin, executionAdmin) {\n _admin = sandAdmin;\n if (beneficiary != address(0)) {\n uint256 initialSupply = amount * (1 ether);\n _mint(beneficiary, initialSupply);\n }\n }\n}\n" + }, + "src/solc_0.8/StarterPack/PurchaseValidator.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {AccessControl, Context} from \"@openzeppelin/contracts-0.8/access/AccessControl.sol\";\nimport {EIP712, ECDSA} from \"@openzeppelin/contracts-0.8/utils/cryptography/draft-EIP712.sol\";\n\n/// @title Purchase Validator contract that validates the purchase of catalysts and gems bundles with EIP712\n/// @notice This contract manages the validation of purchases\n/// @notice The following privileged roles are used in PurchaseValidator: DEFAULT_ADMIN_ROLE\n/// @dev It is intended that this contract is inherited by StarterPack\ncontract PurchaseValidator is AccessControl, EIP712 {\n address private _signingWallet;\n\n // A parallel-queue mapping to nonces: user => (queueID => nonce)\n mapping(address => mapping(uint128 => uint128)) public queuedNonces;\n\n bytes32 public constant PURCHASE_TYPEHASH =\n keccak256(\n \"Purchase(address buyer,uint16[] catalystIds,uint256[] catalystQuantities,uint16[] gemIds,uint256[] gemQuantities,uint256 nonce)\"\n );\n\n event SigningWallet(address indexed newSigningWallet);\n\n constructor(\n address initialSigningWallet,\n string memory name,\n string memory version\n ) EIP712(name, version) {\n require(initialSigningWallet != address(0), \"WALLET_ZERO_ADDRESS\");\n _signingWallet = initialSigningWallet;\n }\n\n /// @notice Update the signing wallet address\n /// @param newSigningWallet The new address of the signing wallet\n function setSigningWallet(address newSigningWallet) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(newSigningWallet != address(0), \"WALLET_ZERO_ADDRESS\");\n require(newSigningWallet != _signingWallet, \"WALLET_ALREADY_SET\");\n _signingWallet = newSigningWallet;\n emit SigningWallet(newSigningWallet);\n }\n\n /// @notice Function to get the nonce for a given address and queue ID\n /// @param _buyer The address of the starterPack purchaser\n /// @param _queueId The ID of the nonce queue for the given address.\n /// The default is queueID=0, and the max is queueID=2**128-1\n /// @return uint128 representing the requested nonce\n function getNonceByBuyer(address _buyer, uint128 _queueId) external view returns (uint128) {\n return queuedNonces[_buyer][_queueId];\n }\n\n /// @notice Function to get the domain separator\n function domainSeparator() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Function to get the chainId\n function getChainId() external view returns (uint256) {\n return block.chainid;\n }\n\n /// @notice Get the wallet authorized for signing purchase-messages.\n /// @return _signingWallet the address of the signing wallet\n function getSigningWallet() external view returns (address) {\n return _signingWallet;\n }\n\n /// @notice Check if a purchase message is valid by verifying a EIP712 signature for the purchase message\n /// @dev It is intended that this contract is inherited so this internal function can be used\n /// @param buyer The address paying for the purchase & receiving tokens\n /// @param catalystIds The catalyst IDs to be purchased\n /// @param catalystQuantities The quantities of the catalysts to be purchased\n /// @param gemIds The gem IDs to be purchased\n /// @param gemQuantities The quantities of the gems to be purchased\n /// @param nonce The current nonce for the user. This is represented as a\n /// uint256 value, but is actually 2 packed uint128's (queueId + nonce)\n /// @param signature A signed message specifying tx details\n /// @return true if the purchase is valid\n function _isPurchaseValid(\n address buyer,\n uint16[] memory catalystIds,\n uint256[] memory catalystQuantities,\n uint16[] memory gemIds,\n uint256[] memory gemQuantities,\n uint256 nonce,\n bytes memory signature\n ) internal returns (bool) {\n require(_checkAndUpdateNonce(buyer, nonce), \"INVALID_NONCE\");\n bytes32 digest =\n _hashTypedDataV4(\n keccak256(\n abi.encode(\n PURCHASE_TYPEHASH,\n buyer,\n keccak256(abi.encodePacked(catalystIds)),\n keccak256(abi.encodePacked(catalystQuantities)),\n keccak256(abi.encodePacked(gemIds)),\n keccak256(abi.encodePacked(gemQuantities)),\n nonce\n )\n )\n );\n address recoveredSigner = ECDSA.recover(digest, signature);\n return recoveredSigner == _signingWallet;\n }\n\n /// @dev Function for validating the nonce for a user.\n /// @param _buyer The address for which we want to check the nonce\n /// @param _packedValue The queueId + nonce, packed together.\n /// @return bool Whether the nonce is valid.\n /// EG: for queueId=42 nonce=7, pass: \"0x0000000000000000000000000000002A00000000000000000000000000000007\"\n function _checkAndUpdateNonce(address _buyer, uint256 _packedValue) private returns (bool) {\n uint128 queueId = uint128(_packedValue / 2**128);\n uint128 nonce = uint128(_packedValue % 2**128);\n uint128 currentNonce = queuedNonces[_buyer][queueId];\n if (nonce == currentNonce) {\n queuedNonces[_buyer][queueId] = currentNonce + 1;\n return true;\n }\n return false;\n }\n}\n" + }, + "src/solc_0.8/test/ContributionCalculatorMock.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport \"../defi/interfaces/IContributionCalculator.sol\";\n\ncontract ContributionCalculatorMock is IContributionCalculator {\n mapping(address => uint256) public contribution;\n\n function computeContribution(address account, uint256) external view override returns (uint256) {\n return contribution[account];\n }\n\n function setContribution(address account, uint256 contribution_) external {\n contribution[account] = contribution_;\n }\n}\n" + }, + "src/solc_0.8/test/ContributionRulesMock.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport \"../defi/interfaces/IContributionRules.sol\";\n\ncontract ContributionRulesMock is IContributionRules {\n mapping(address => uint256) public contribution;\n\n function computeMultiplier(address account, uint256) external view override returns (uint256) {\n return contribution[account];\n }\n\n function setContribution(address account, uint256 contribution_) external {\n contribution[account] = contribution_;\n }\n}\n" + }, + "src/solc_0.8/test/EmptyContract.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\n// solhint-disable-next-line no-empty-blocks\ncontract EmptyContract {\n\n}\n" + }, + "src/solc_0.8/test/ERC1155Mintable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {ERC1155} from \"@openzeppelin/contracts-0.8/token/ERC1155/ERC1155.sol\";\n\n/// @dev This is NOT a secure ERC1155\n/// DO NOT USE in production.\ncontract ERC1155Mintable is ERC1155 {\n mapping(uint256 => mapping(address => uint256)) public fakeBalance;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(string memory uri_) ERC1155(uri_) {}\n\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external {\n _mint(to, id, amount, data);\n }\n\n function balanceOf(address owner, uint256 id) public view override returns (uint256) {\n if (fakeBalance[id][owner] != 0) {\n return fakeBalance[id][owner];\n }\n return ERC1155.balanceOf(owner, id);\n }\n\n function setFakeBalance(\n address owner,\n uint256 id,\n uint256 balance\n ) external {\n fakeBalance[id][owner] = balance;\n }\n}\n" + }, + "src/solc_0.8/test/ERC20Mintable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {ERC20} from \"@openzeppelin/contracts-0.8/token/ERC20/ERC20.sol\";\n\n/// @dev This is NOT a secure ERC20\n/// DO NOT USE in production.\ncontract ERC20Mintable is ERC20 {\n // solhint-disable-next-line no-empty-blocks\n constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n }\n}\n" + }, + "src/solc_0.8/test/ERC721Mintable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {ERC721} from \"@openzeppelin/contracts-0.8/token/ERC721/ERC721.sol\";\n\n/// @dev This is NOT a secure ERC721\n/// DO NOT USE in production.\ncontract ERC721Mintable is ERC721 {\n mapping(address => uint256) public fakeBalance;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}\n\n function mint(address to, uint256 tokenId) external {\n _mint(to, tokenId);\n }\n\n function balanceOf(address owner) public view override returns (uint256) {\n if (fakeBalance[owner] != 0) {\n return fakeBalance[owner];\n }\n return ERC721.balanceOf(owner);\n }\n\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return ERC721.ownerOf(tokenId);\n }\n\n function setFakeBalance(address owner, uint256 balance) external {\n fakeBalance[owner] = balance;\n }\n}\n" + }, + "src/solc_0.8/test/FakeCheckpointManager.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\ncontract ICheckpointManager {\n struct HeaderBlock {\n bytes32 root;\n uint256 start;\n uint256 end;\n uint256 createdAt;\n address proposer;\n }\n\n /**\n * @notice mapping of checkpoint header numbers to block details\n * @dev These checkpoints are submited by plasma contracts\n */\n mapping(uint256 => HeaderBlock) public headerBlocks;\n}\n\ncontract FakeCheckpointManager is ICheckpointManager {\n uint256 public currentCheckpointNumber = 0;\n\n function setCheckpoint(\n bytes32 rootHash,\n uint256 start,\n uint256 end\n ) public {\n HeaderBlock memory headerBlock =\n HeaderBlock({root: rootHash, start: start, end: end, createdAt: block.timestamp, proposer: msg.sender});\n\n currentCheckpointNumber = currentCheckpointNumber + 1;\n headerBlocks[currentCheckpointNumber] = headerBlock;\n }\n}\n" + }, + "src/solc_0.8/test/FakeChildChainManager.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\n//import \"../polygon/child/asset/PolygonAssetERC1155.sol\";\nimport \"../test/MockERC1155Asset.sol\";\nimport \"../polygon/child/sand/PolygonSand.sol\";\n\n/// @dev This is NOT a secure ChildChainManager contract implementation!\n/// DO NOT USE in production.\n\ncontract FakeChildChainManager {\n address public polygonAsset;\n\n // solhint-disable-next-line no-empty-blocks\n constructor() {}\n\n function setPolygonAsset(address _polygonAsset) external {\n polygonAsset = _polygonAsset;\n }\n\n function callDeposit(address user, bytes calldata depositData) external {\n MockERC1155Asset(polygonAsset).deposit(user, depositData);\n }\n\n function callSandDeposit(\n address polygonSand,\n address user,\n bytes calldata depositData\n ) external {\n PolygonSand(polygonSand).deposit(user, depositData);\n }\n}\n" + }, + "src/solc_0.8/test/FakeERC1155Predicate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {IERC1155} from \"@openzeppelin/contracts-0.8/token/ERC1155/IERC1155.sol\";\nimport {ERC1155Receiver} from \"@openzeppelin/contracts-0.8/token/ERC1155/utils/ERC1155Receiver.sol\";\n\ninterface IMintableERC1155 is IERC1155 {\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n\n/// @dev This is NOT a secure ChildChainManager contract implementation!\n/// DO NOT USE in production.\n\ncontract FakeERC1155Predicate is ERC1155Receiver {\n address private asset;\n\n function setAsset(address _asset) external {\n asset = _asset;\n }\n\n function lockTokens(\n address depositor,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external {\n IMintableERC1155(asset).safeBatchTransferFrom(depositor, address(this), ids, amounts, data);\n }\n\n function exitTokens(\n address withdrawer,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public {\n IMintableERC1155 token = IMintableERC1155(asset);\n uint256[] memory balances = token.balanceOfBatch(makeArrayWithAddress(address(this), ids.length), ids);\n (uint256[] memory toBeMinted, bool needMintStep, bool needTransferStep) =\n calculateAmountsToBeMinted(balances, amounts);\n if (needMintStep) {\n token.mintBatch(\n withdrawer,\n ids,\n toBeMinted,\n data // passing data when minting to withdrawer\n );\n }\n if (needTransferStep) {\n token.safeBatchTransferFrom(\n address(this),\n withdrawer,\n ids,\n balances,\n data // passing data when transferring unlocked tokens to withdrawer\n );\n }\n }\n\n function calculateAmountsToBeMinted(uint256[] memory balances, uint256[] memory exitAmounts)\n internal\n pure\n returns (\n uint256[] memory,\n bool,\n bool\n )\n {\n uint256 count = balances.length;\n require(count == exitAmounts.length, \"ChainExitERC1155Predicate: Array length mismatch found\");\n uint256[] memory toBeMinted = new uint256[](count);\n bool needMintStep;\n bool needTransferStep;\n for (uint256 i = 0; i < count; i++) {\n if (balances[i] < exitAmounts[i]) {\n toBeMinted[i] = exitAmounts[i] - balances[i];\n needMintStep = true;\n }\n if (balances[i] != 0) {\n needTransferStep = true;\n }\n }\n return (toBeMinted, needMintStep, needTransferStep);\n }\n\n function makeArrayWithAddress(address addr, uint256 size) internal pure returns (address[] memory) {\n require(addr != address(0), \"MintableERC1155Predicate: Invalid address\");\n require(size > 0, \"MintableERC1155Predicate: Invalid resulting array length\");\n address[] memory addresses = new address[](size);\n for (uint256 i = 0; i < size; i++) {\n addresses[i] = addr;\n }\n return addresses;\n }\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return 0;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return ERC1155Receiver(address(0)).onERC1155BatchReceived.selector;\n }\n}\n" + }, + "src/solc_0.8/test/FakeERC20Predicate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport {SafeERC20} from \"@openzeppelin/contracts-0.8/token/ERC20/utils/SafeERC20.sol\";\nimport {IERC20} from \"@openzeppelin/contracts-0.8/token/ERC20/IERC20.sol\";\n\n/// @dev This is NOT a secure ERC20 Predicate contract implementation!\n/// DO NOT USE in production.\n\ncontract FakeERC20Predicate {\n address private token;\n using SafeERC20 for IERC20;\n\n event LockedERC20(\n address indexed depositor,\n address indexed depositReceiver,\n address indexed rootToken,\n uint256 amount\n );\n\n function setToken(address _token) external {\n token = _token;\n }\n\n function lockTokens(\n address depositor,\n address depositReceiver,\n bytes calldata depositData\n ) external {\n uint256 amount = abi.decode(depositData, (uint256));\n emit LockedERC20(depositor, depositReceiver, token, amount);\n IERC20(token).safeTransferFrom(depositor, address(this), amount);\n }\n\n function exitTokens(address withdrawer, uint256 amount) public {\n IERC20(token).safeTransfer(withdrawer, amount);\n }\n}\n" + }, + "src/solc_0.8/test/FakeFxRoot.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../common/interfaces/IPolygonLand.sol\";\n\n// solhint-disable\n\n/// @dev This is NOT a secure FxRoot contract implementation!\n/// DO NOT USE in production.\n\ninterface IFakeFxChild {\n function onStateReceive(\n uint256 stateId,\n address receiver,\n address rootMessageSender,\n bytes memory data\n ) external;\n}\n\n/**\n * @title FxRoot root contract for fx-portal\n */\ncontract FakeFxRoot {\n address fxChild;\n\n function setFxChild(address _fxChild) public {\n fxChild = _fxChild;\n }\n\n function sendMessageToChild(address _receiver, bytes calldata _data) public {\n IFakeFxChild(fxChild).onStateReceive(0, _receiver, msg.sender, _data);\n }\n}\n" + }, + "src/solc_0.8/test/FakeLPSandMatic.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"../common/BaseWithStorage/ERC20/ERC20BaseToken.sol\";\n\ncontract FakeLPSandMatic is ERC20BaseToken {\n constructor() ERC20BaseToken(\"LPSandMatic\", \"LPSM\", msg.sender, msg.sender) {\n _mint(msg.sender, 3000000000 * 10**18);\n }\n}\n" + }, + "src/solc_0.8/test/FakeMintableERC721Predicate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"../common/interfaces/IMintableERC721.sol\";\nimport \"../common/interfaces/IERC721TokenReceiver.sol\";\n\n/// @dev based on: @maticnetwork/pos-portal/contracts/root/TokenPredicates/MintableERC721Predicate.sol\n/// @dev This is NOT a secure ERC721 Predicate contract implementation!\n/// DO NOT USE in production.\n\ncontract FakeMintableERC721Predicate is IERC721TokenReceiver {\n /**\n * @notice Lock ERC721 token(s) for deposit, callable only by manager\n * @param depositor Address who wants to deposit token\n * @param rootToken Token which gets deposited\n * @param depositData ABI encoded tokenId(s). It's possible to deposit batch of tokens.\n */\n function lockTokens(\n address depositor,\n address rootToken,\n bytes calldata depositData\n ) external {\n // Locking single ERC721 token\n if (depositData.length == 32) {\n uint256 tokenId = abi.decode(depositData, (uint256));\n\n // Emitting event that single token is getting locked in predicate\n // emit LockedMintableERC721(depositor, depositReceiver, rootToken, tokenId);\n\n // Transferring token to this address, which will be\n // released when attempted to be unlocked\n IMintableERC721(rootToken).safeTransferFrom(depositor, address(this), tokenId);\n } else {\n // Locking a set a ERC721 token(s)\n\n uint256[] memory tokenIds = abi.decode(depositData, (uint256[]));\n\n // Emitting event that a set of ERC721 tokens are getting lockec\n // in this predicate contract\n // emit LockedMintableERC721Batch(depositor, depositReceiver, rootToken, tokenIds);\n\n // These many tokens are attempted to be deposited\n // by user\n uint256 length = tokenIds.length;\n // Iteratively trying to transfer ERC721 token\n // to this predicate address\n for (uint256 i; i < length; i++) {\n IMintableERC721(rootToken).safeTransferFrom(depositor, address(this), tokenIds[i]);\n }\n }\n }\n\n /**\n * @notice Validates log signature, from and to address\n * then checks if token already exists on root chain\n * if token exits then transfers it to withdrawer\n * if token doesn't exit then it is minted\n * callable only by manager\n */\n function exitTokens(\n address rootToken,\n address withdrawer,\n uint256 tokenId\n ) public {\n // If it's a simple exit ( with out metadata coming from L2 to L1 )\n IMintableERC721 token = IMintableERC721(rootToken);\n\n // topic3 is tokenId field\n if (token.exists(tokenId)) {\n token.safeTransferFrom(address(this), withdrawer, tokenId);\n } else {\n token.mint(withdrawer, tokenId);\n }\n }\n\n function exitTokens(\n address rootToken,\n address withdrawer,\n uint256[] calldata tokenIds\n ) public {\n // topic0 is event sig\n // If it's a simple batch exit, where a set of\n // ERC721s were burnt in child chain with event signature\n // looking like `WithdrawnBatch(address indexed user, uint256[] tokenIds);`\n //\n // @note This doesn't allow transfer of metadata cross chain\n // For that check below `else if` block\n // topic1 is from address\n\n uint256 length = tokenIds.length;\n IMintableERC721 token = IMintableERC721(rootToken);\n for (uint256 i; i < length; i++) {\n uint256 tokenId = tokenIds[i];\n\n // Check if token exists or not\n //\n // If does, transfer token to withdrawer\n if (token.exists(tokenId)) {\n token.safeTransferFrom(address(this), withdrawer, tokenId);\n } else {\n // If token was minted on L2\n // we'll mint it here, on L1, during\n // exiting from L2\n token.mint(withdrawer, tokenId);\n }\n }\n }\n\n function exitTokens(\n address rootToken,\n address withdrawer,\n uint256 tokenId,\n bytes calldata metadata\n ) public {\n // If this is NFT exit with metadata i.e. URI 👆\n //\n // Note: If your token is only minted in L2, you can exit\n // it with metadata. But if it was minted on L1, it'll be\n // simply transferred to withdrawer address. And in that case,\n // it's lot better to exit with `Transfer(address,address,uint256)`\n // i.e. calling `withdraw` method on L2 contract\n // event signature proof, which is defined under first `if` clause\n //\n // If you've called `withdrawWithMetadata`, you should submit\n // proof of event signature `TransferWithMetadata(address,address,uint256,bytes)`\n\n IMintableERC721 token = IMintableERC721(rootToken);\n\n // topic3 is tokenId field\n if (token.exists(tokenId)) {\n token.safeTransferFrom(address(this), withdrawer, tokenId);\n } else {\n token.mint(withdrawer, tokenId, metadata);\n }\n }\n\n /**\n * @notice accepts safe ERC721 transfer\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721TokenReceiver.onERC721Received.selector;\n }\n}\n" + }, + "src/solc_0.8/test/FakePolygonLand.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"../common/BaseWithStorage/ERC20/ERC20BaseToken.sol\";\n\ncontract FakePolygonLand is ERC20BaseToken {\n constructor() ERC20BaseToken(\"FakePolygonLand\", \"FPL\", msg.sender, msg.sender) {\n _mint(msg.sender, 3000000000 * 10**18);\n }\n}\n" + }, + "src/solc_0.8/test/FakePolygonSand.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"../common/BaseWithStorage/ERC20/ERC20BaseToken.sol\";\n\ncontract FakePolygonSand is ERC20BaseToken {\n constructor() ERC20BaseToken(\"FakePolygonSand\", \"FPS\", msg.sender, msg.sender) {\n _mint(msg.sender, 3000000000 * 10**18);\n }\n}\n" + }, + "src/solc_0.8/test/FakePredicateForwarder.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\n/// @dev This is NOT a secure forwarder contract implementation!\n/// DO NOT USE in production.\ncontract FakePredicateForwarder {\n struct Request {\n address from;\n address to;\n uint256 value;\n uint256 gas;\n bytes data;\n }\n\n // solhint-disable-next-line no-empty-blocks\n constructor() {}\n\n function forward(Request calldata req) public returns (bool, bytes memory) {\n // solhint-disable avoid-low-level-calls\n (bool success, bytes memory returndata) =\n req.to.call{gas: req.gas, value: req.value}(abi.encodePacked(req.data, req.from));\n // solhint-enable avoid-low-level-calls\n\n return (success, returndata);\n }\n}\n" + }, + "src/solc_0.8/test/FallbackContract.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\ncontract FallBackContract {\n // solhint-disable-next-line payable-fallback\n fallback() external {}\n}\n" + }, + "src/solc_0.8/test/MockERC1155Asset.sol": { + "content": "//SPDX-License-Identifier: MIT\n\n/* solhint-disable no-empty-blocks */\n\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/token/ERC1155/presets/ERC1155PresetMinterPauser.sol\";\nimport \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\n\ncontract MockERC1155Asset is ERC1155PresetMinterPauser, Ownable {\n event Bouncer(address indexed bouncer, bool indexed enabled);\n\n constructor(string memory uri) ERC1155PresetMinterPauser(uri) Ownable() {}\n\n function setBouncer(address bouncer, bool enabled) external {\n emit Bouncer(bouncer, enabled);\n }\n\n function mint(\n address creator,\n uint40 packId,\n bytes32 hash,\n uint256 supply,\n address owner,\n bytes calldata data\n ) external {\n _mint(owner, packId, supply, data);\n }\n\n function deposit(address user, bytes calldata depositData) external {\n (uint256[] memory ids, uint256[] memory amounts, bytes memory data) =\n abi.decode(depositData, (uint256[], uint256[], bytes));\n emit TransferBatch(_msgSender(), address(0), user, ids, amounts);\n }\n}\n" + }, + "src/solc_0.8/test/MockERC20BasicApprovalTarget.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/token/ERC20/IERC20.sol\";\n\ncontract MockERC20BasicApprovalTarget {\n event LogOnCall(address);\n\n function logOnCall(address sender) external returns (address) {\n emit LogOnCall(sender);\n return sender;\n }\n\n function revertOnCall() external pure {\n revert(\"REVERT_ON_CALL\");\n }\n\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool) {\n return IERC20(msg.sender).transferFrom(sender, recipient, amount);\n }\n}\n" + }, + "src/solc_0.8/test/MockERC667Reciever.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\nimport \"../common/interfaces/IERC677Receiver.sol\";\n\ncontract MockERC677Receiver is IERC677Receiver {\n event OnTokenTransferEvent(address indexed _sender, uint256 _value, bytes _data);\n\n /// @dev Emits the OnTokenTransferEvent.\n /// @param _sender The address of the sender.\n /// @param _value The value sent with the tx.\n /// @param _data The data sent with the tx.\n function onTokenTransfer(\n address _sender,\n uint256 _value,\n bytes calldata _data\n ) external override {\n emit OnTokenTransferEvent(_sender, _value, _data);\n }\n}\n" + }, + "src/solc_0.8/test/MockERC721Asset.sol": { + "content": "//SPDX-License-Identifier: MIT\n\n/* solhint-disable no-empty-blocks */\n\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol\";\nimport \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\n\ncontract MockERC721Asset is ERC721PresetMinterPauserAutoId, Ownable {\n constructor(\n string memory name,\n string memory symbol,\n string memory uri\n ) ERC721PresetMinterPauserAutoId(name, symbol, uri) Ownable() {}\n}\n" + }, + "src/solc_0.8/test/MockLandV2WithMint.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable code-complexity\npragma solidity 0.8.2;\n\nimport \"../polygon/child/land/PolygonLandBaseTokenV2.sol\";\n\ncontract MockLandV2WithMint is PolygonLandBaseTokenV2 {\n /** @notice Removed caller validations */\n function mintQuad(\n address user,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes memory data\n ) external override {\n _mintQuad(user, size, x, y, data);\n }\n\n /** @notice Removed caller validations */\n function mintAndTransferQuad(\n address to,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes calldata data\n ) external override {\n require(to != address(0), \"to is zero address\");\n\n if (exists(size, x, y)) {\n _transferQuad(msg.sender, to, size, x, y);\n _numNFTPerAddress[msg.sender] -= size * size;\n _numNFTPerAddress[to] += size * size;\n _checkBatchReceiverAcceptQuad(msg.sender, msg.sender, to, size, x, y, data);\n } else {\n _mintAndTransferQuad(to, size, x, y, data);\n }\n }\n}\n" + }, + "src/solc_0.8/test/MockLandWithMint.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable code-complexity\npragma solidity 0.8.2;\n\nimport \"../polygon/child/land/PolygonLandBaseToken.sol\";\n\ncontract MockLandWithMint is PolygonLandBaseToken {\n /** @notice Removed caller validations */\n function mint(\n address user,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes memory data\n ) external {\n _mintQuad(user, size, x, y, data);\n }\n\n function mintQuad(\n address user,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes memory data\n ) external override {\n _mintQuad(user, size, x, y, data);\n }\n}\n" + }, + "src/solc_0.8/test/MockMarketPlace1.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\nimport {IAssetERC721} from \"../common/interfaces/IAssetERC721.sol\";\nimport {IAssetERC1155} from \"../common/interfaces/IAssetERC1155.sol\";\nimport {ILandTokenV3} from \"../common/interfaces/ILandTokenV3.sol\";\n\ncontract MockMarketPlace1 {\n bytes4 private constant ERC721_IS_RECEIVER = 0x150b7a02;\n bytes4 private constant ERC721_RECEIVED = 0x150b7a02;\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function transferTokenForERC1155(\n address asset,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external {\n IAssetERC1155(asset).safeTransferFrom(from, to, id, amount, data);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param land the contract address on which the token transfer will take place\n /// @param from adderess from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param data aditional data accompanying the transfer.\n function transferLand(\n address land,\n address from,\n address to,\n uint256 id,\n bytes memory data\n ) external {\n ILandTokenV3(land).safeTransferFrom(from, to, id, data);\n }\n\n /// @notice Transfer tokens with given ids ensuring the receiving contract has a receiver method.\n /// @param asset the contract address on which the token transfer will take place\n /// @param from Address whose token is to be transferred.\n /// @param to Recipient.\n /// @param id The token id to be transferred.\n function transferTokenERC721(\n address asset,\n address from,\n address to,\n uint256 id\n ) external {\n IAssetERC721(asset).safeTransferFrom(from, to, id);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function batchTransferTokenERC1155(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external {\n IAssetERC1155(asset).safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /// @notice Transfer tokens with given ids ensuring the receiving contract has a receiver method.\n /// @param asset the contract address on which the token transfer will take place\n /// @param from The sender of the tokens.\n /// @param to The recipient of the tokens.\n /// @param ids The ids of the tokens to be transferred.\n /// @param data Additional data.\n function batchTransferTokenERC721(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n bytes memory data\n ) external {\n IAssetERC721(asset).safeBatchTransferFrom(from, to, ids, data);\n }\n\n /// @notice Transfer tokens with given ids ensuring the receiving contract has a receiver method.\n /// @param land the contract address on which the token transfer will take place\n /// @param from The sender of the tokens.\n /// @param to The recipient of the tokens.\n /// @param id The id of the token to be transferred.\n function transferLand(\n address land,\n address from,\n address to,\n uint256 id\n ) external {\n ILandTokenV3(land).safeTransferFrom(from, to, id);\n }\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC721_RECEIVED;\n }\n\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n return _interfaceId == 0x01ffc9a7 || _interfaceId == ERC1155_IS_RECEIVER || _interfaceId == ERC721_IS_RECEIVER;\n }\n}\n" + }, + "src/solc_0.8/test/MockMarketPlace2.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\nimport {IAssetERC721} from \"../common/interfaces/IAssetERC721.sol\";\nimport {IAssetERC1155} from \"../common/interfaces/IAssetERC1155.sol\";\nimport {ILandTokenV3} from \"../common/interfaces/ILandTokenV3.sol\";\n\ncontract MockMarketPlace2 {\n bytes4 private constant ERC721_IS_RECEIVER = 0x150b7a02;\n bytes4 private constant ERC721_RECEIVED = 0x150b7a02;\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function transferTokenForERC1155(\n address asset,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external {\n IAssetERC1155(asset).safeTransferFrom(from, to, id, amount, data);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param land the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param data aditional data accompanying the transfer.\n function transferLand(\n address land,\n address from,\n address to,\n uint256 id,\n bytes memory data\n ) external {\n ILandTokenV3(land).safeTransferFrom(from, to, id, data);\n }\n\n /// @notice Transfer tokens with given ids ensuring the receiving contract has a receiver method.\n /// @param asset the contract address on which the token transfer will take place\n /// @param from Address whose token is to be transferred.\n /// @param to Recipient.\n /// @param id The token id to be transferred.\n function transferTokenERC721(\n address asset,\n address from,\n address to,\n uint256 id\n ) external {\n IAssetERC721(asset).safeTransferFrom(from, to, id);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function batchTransferTokenERC1155(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external {\n IAssetERC1155(asset).safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /// @notice Transfer tokens with given ids ensuring the receiving contract has a receiver method.\n /// @param asset the contract address on which the token transfer will take place\n /// @param from The sender of the tokens.\n /// @param to The recipient of the tokens.\n /// @param ids The ids of the tokens to be transferred.\n /// @param data Additional data.\n function batchTransferTokenERC721(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n bytes memory data\n ) external {\n IAssetERC721(asset).safeBatchTransferFrom(from, to, ids, data);\n }\n\n /// @notice Transfer tokens with given ids ensuring the receiving contract has a receiver method.\n /// @param land the contract address on which the token transfer will take place\n /// @param from The sender of the tokens.\n /// @param to The recipient of the tokens.\n /// @param id The id of the token to be transferred.\n function transferLand(\n address land,\n address from,\n address to,\n uint256 id\n ) external {\n ILandTokenV3(land).safeTransferFrom(from, to, id);\n }\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC721_RECEIVED;\n }\n\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n return _interfaceId == 0x01ffc9a7 || _interfaceId == ERC1155_IS_RECEIVER || _interfaceId == ERC721_IS_RECEIVER;\n }\n}\n" + }, + "src/solc_0.8/test/MockMarketPlace3.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\nimport {IAssetERC721} from \"../common/interfaces/IAssetERC721.sol\";\nimport {IAssetERC1155} from \"../common/interfaces/IAssetERC1155.sol\";\nimport {ILandTokenV3} from \"../common/interfaces/ILandTokenV3.sol\";\n\ncontract MockMarketPlace3 {\n bytes4 private constant ERC721_IS_RECEIVER = 0x150b7a02;\n bytes4 private constant ERC721_RECEIVED = 0x150b7a02;\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function transferTokenForERC1155(\n address asset,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external {\n IAssetERC1155(asset).safeTransferFrom(from, to, id, amount, data);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param land the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param data aditional data accompanying the transfer.\n function transferLand(\n address land,\n address from,\n address to,\n uint256 id,\n bytes memory data\n ) external {\n ILandTokenV3(land).safeTransferFrom(from, to, id, data);\n }\n\n /// @notice Transfer tokens with given ids ensuring the receiving contract has a receiver method.\n /// @param asset the contract address on which the token transfer will take place\n /// @param from Address whose token is to be transferred.\n /// @param to Recipient.\n /// @param id The token id to be transferred.\n function transferTokenERC721(\n address asset,\n address from,\n address to,\n uint256 id\n ) external {\n IAssetERC721(asset).safeTransferFrom(from, to, id);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function batchTransferTokenERC1155(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external {\n IAssetERC1155(asset).safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /// @notice Transfer tokens with given ids ensuring the receiving contract has a receiver method.\n /// @param asset the contract address on which the token transfer will take place\n /// @param from The sender of the tokens.\n /// @param to The recipient of the tokens.\n /// @param ids The ids of the tokens to be transferred.\n /// @param data Additional data.\n function batchTransferTokenERC721(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n bytes memory data\n ) external {\n IAssetERC721(asset).safeBatchTransferFrom(from, to, ids, data);\n }\n\n /// @notice Transfer tokens with given ids ensuring the receiving contract has a receiver method.\n /// @param land the contract address on which the token transfer will take place\n /// @param from The sender of the tokens.\n /// @param to The recipient of the tokens.\n /// @param id The id of the token to be transferred.\n function transferLand(\n address land,\n address from,\n address to,\n uint256 id\n ) external {\n ILandTokenV3(land).safeTransferFrom(from, to, id);\n }\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC721_RECEIVED;\n }\n\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n return _interfaceId == 0x01ffc9a7 || _interfaceId == ERC1155_IS_RECEIVER || _interfaceId == ERC721_IS_RECEIVER;\n }\n}\n" + }, + "src/solc_0.8/test/MockMarketPlace4.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\nimport {IAssetERC721} from \"../common/interfaces/IAssetERC721.sol\";\nimport {IAssetERC1155} from \"../common/interfaces/IAssetERC1155.sol\";\nimport {ILandTokenV3} from \"../common/interfaces/ILandTokenV3.sol\";\n\ncontract MockMarketPlace4 {\n bytes4 private constant ERC721_IS_RECEIVER = 0x150b7a02;\n bytes4 private constant ERC721_RECEIVED = 0x150b7a02;\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function transferTokenForERC1155(\n address asset,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external {\n IAssetERC1155(asset).safeTransferFrom(from, to, id, amount, data);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param land the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param data aditional data accompanying the transfer.\n function transferLand(\n address land,\n address from,\n address to,\n uint256 id,\n bytes memory data\n ) external {\n ILandTokenV3(land).safeTransferFrom(from, to, id, data);\n }\n\n /// @notice Transfer tokens with given ids ensuring the receiving contract has a receiver method.\n /// @param asset the contract address on which the token transfer will take place\n /// @param from Address whose token is to be transferred.\n /// @param to Recipient.\n /// @param id The token id to be transferred.\n function transferTokenERC721(\n address asset,\n address from,\n address to,\n uint256 id\n ) external {\n IAssetERC721(asset).safeTransferFrom(from, to, id);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function batchTransferTokenERC1155(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external {\n IAssetERC1155(asset).safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /// @notice Transfer tokens with given ids ensuring the receiving contract has a receiver method.\n /// @param asset the contract address on which the token transfer will take place\n /// @param from The sender of the tokens.\n /// @param to The recipient of the tokens.\n /// @param ids The ids of the tokens to be transferred.\n /// @param data Additional data.\n function batchTransferTokenERC721(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n bytes memory data\n ) external {\n IAssetERC721(asset).safeBatchTransferFrom(from, to, ids, data);\n }\n\n /// @notice Transfer tokens with given ids ensuring the receiving contract has a receiver method.\n /// @param land the contract address on which the token transfer will take place\n /// @param from The sender of the tokens.\n /// @param to The recipient of the tokens.\n /// @param id The id of the token to be transferred.\n function transferLand(\n address land,\n address from,\n address to,\n uint256 id\n ) external {\n ILandTokenV3(land).safeTransferFrom(from, to, id);\n }\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC721_RECEIVED;\n }\n\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n return _interfaceId == 0x01ffc9a7 || _interfaceId == ERC1155_IS_RECEIVER || _interfaceId == ERC721_IS_RECEIVER;\n }\n}\n" + }, + "src/solc_0.8/test/MockOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable code-complexity\npragma solidity 0.8.2;\n\nimport {IOperatorFilterRegistry} from \"../OperatorFilterer/interfaces/IOperatorFilterRegistry.sol\";\nimport {Ownable} from \"@openzeppelin/contracts-0.8/access/Ownable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts-0.8/utils/structs/EnumerableSet.sol\";\nimport {OperatorFilterRegistryEvents} from \"./OperatorFilterRegistryEvents.sol\";\n\n/**\n * @title MockOperatorFilterRegistry\n * @notice Made based on the OperatorFilterRegistry of openSea at https://github.com/ProjectOpenSea/operator-filter-registry/blob/main/src/OperatorFilterRegistry.sol\n * @notice This contracts allows tokens or token owners to register specific addresses or codeHashes that may be\n * * restricted according to the isOperatorAllowed function.\n */\ncontract MockOperatorFilterRegistry is IOperatorFilterRegistry, OperatorFilterRegistryEvents {\n using EnumerableSet for EnumerableSet.AddressSet;\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n /// @dev initialized accounts have a nonzero codehash (see https://eips.ethereum.org/EIPS/eip-1052)\n /// Note that this will also be a smart contract's codehash when making calls from its constructor.\n bytes32 public constant EOA_CODEHASH = keccak256(\"\");\n\n mapping(address => EnumerableSet.AddressSet) private _filteredOperators;\n mapping(address => EnumerableSet.Bytes32Set) private _filteredCodeHashes;\n mapping(address => address) private _registrations;\n mapping(address => EnumerableSet.AddressSet) private _subscribers;\n\n constructor(address _defaultSubscribtion, address[] memory _blacklistedAddresses) {\n _registrations[_defaultSubscribtion] = _defaultSubscribtion;\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[_defaultSubscribtion];\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[_defaultSubscribtion];\n for (uint256 i; i < _blacklistedAddresses.length; i++) {\n filteredOperatorsRef.add(_blacklistedAddresses[i]);\n bytes32 codeHash = _blacklistedAddresses[i].codehash;\n filteredCodeHashesRef.add(codeHash);\n }\n }\n\n /**\n * @notice restricts method caller to the address or EIP-173 \"owner()\"\n */\n modifier onlyAddressOrOwner(address addr) {\n if (msg.sender != addr) {\n try Ownable(addr).owner() returns (address owner) {\n if (msg.sender != owner) {\n revert(\"Only Address or Owner\");\n }\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"Not Ownable\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n }\n _;\n }\n\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n */\n function isOperatorAllowed(address registrant, address operator) external view override returns (bool) {\n address registration = _registrations[registrant];\n if (registration != address(0)) {\n EnumerableSet.AddressSet storage filteredOperatorsRef;\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef;\n\n filteredOperatorsRef = _filteredOperators[registration];\n filteredCodeHashesRef = _filteredCodeHashes[registration];\n\n if (filteredOperatorsRef.contains(operator)) {\n revert(\"Address is filtered\");\n }\n if (operator.code.length > 0) {\n bytes32 codeHash = operator.codehash;\n if (filteredCodeHashesRef.contains(codeHash)) {\n revert(\"Codehash is filtered\");\n }\n }\n }\n return true;\n }\n\n //////////////////\n // AUTH METHODS //\n //////////////////\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external override onlyAddressOrOwner(registrant) {\n if (_registrations[registrant] != address(0)) {\n revert(\"Already registered\");\n }\n _registrations[registrant] = registrant;\n emit RegistrationUpdated(registrant, true);\n }\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address registrant) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert(\"Not registered\");\n }\n if (registration != registrant) {\n _subscribers[registration].remove(registrant);\n emit SubscriptionUpdated(registrant, registration, false);\n }\n _registrations[registrant] = address(0);\n emit RegistrationUpdated(registrant, false);\n }\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription)\n external\n override\n onlyAddressOrOwner(registrant)\n {\n address registration = _registrations[registrant];\n if (registration != address(0)) {\n revert(\"Already registered\");\n }\n if (registrant == subscription) {\n revert(\"Cannot subscribe to self\");\n }\n address subscriptionRegistration = _registrations[subscription];\n if (subscriptionRegistration == address(0)) {\n revert(\"Subscribtion not registered\");\n }\n if (subscriptionRegistration != subscription) {\n revert(\"Cannot subscribe to registrant with subscribtion\");\n }\n\n _registrations[registrant] = subscription;\n _subscribers[subscription].add(registrant);\n emit RegistrationUpdated(registrant, true);\n emit SubscriptionUpdated(registrant, subscription, true);\n }\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy)\n external\n override\n onlyAddressOrOwner(registrant)\n {\n if (registrantToCopy == registrant) {\n revert(\"Cannot copy from self\");\n }\n address registration = _registrations[registrant];\n if (registration != address(0)) {\n revert(\"Already registered\");\n }\n address registrantRegistration = _registrations[registrantToCopy];\n if (registrantRegistration == address(0)) {\n revert(\"Registrant to copy from not registered\");\n }\n _registrations[registrant] = registrant;\n emit RegistrationUpdated(registrant, true);\n _copyEntries(registrant, registrantToCopy);\n }\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external override onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert(\"Not registered\");\n }\n if (registration != registrant) {\n revert(\"Cannot update while subscribed\");\n }\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant];\n\n if (!filtered) {\n bool removed = filteredOperatorsRef.remove(operator);\n if (!removed) {\n revert(\"Address not filtered\");\n }\n } else {\n bool added = filteredOperatorsRef.add(operator);\n if (!added) {\n revert(\"Address already filtered\");\n }\n }\n emit OperatorUpdated(registrant, operator, filtered);\n }\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n */\n function updateCodeHash(\n address registrant,\n bytes32 codeHash,\n bool filtered\n ) external override onlyAddressOrOwner(registrant) {\n if (codeHash == EOA_CODEHASH) {\n revert(\"Cannot filter EOAs\");\n }\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert(\"Not registered\");\n }\n if (registration != registrant) {\n revert(\"Cannot update while subscribed\");\n }\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant];\n\n if (!filtered) {\n bool removed = filteredCodeHashesRef.remove(codeHash);\n if (!removed) {\n revert(\"Codehash not filtered\");\n }\n } else {\n bool added = filteredCodeHashesRef.add(codeHash);\n if (!added) {\n revert(\"Codehash already filtered\");\n }\n }\n emit CodeHashUpdated(registrant, codeHash, filtered);\n }\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external override onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert(\"Not registered\");\n }\n if (registration != registrant) {\n revert(\"Cannot update while subscribed\");\n }\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant];\n uint256 operatorsLength = operators.length;\n unchecked {\n if (!filtered) {\n for (uint256 i = 0; i < operatorsLength; ++i) {\n address operator = operators[i];\n bool removed = filteredOperatorsRef.remove(operator);\n if (!removed) {\n revert(\"Address not filtered\");\n }\n }\n } else {\n for (uint256 i = 0; i < operatorsLength; ++i) {\n address operator = operators[i];\n bool added = filteredOperatorsRef.add(operator);\n if (!added) {\n revert(\"Address already filtered\");\n }\n }\n }\n }\n emit OperatorsUpdated(registrant, operators, filtered);\n }\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n */\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external override onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert(\"Not registered\");\n }\n if (registration != registrant) {\n revert(\"Cannot update while subscribed\");\n }\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant];\n uint256 codeHashesLength = codeHashes.length;\n unchecked {\n if (!filtered) {\n for (uint256 i = 0; i < codeHashesLength; ++i) {\n bytes32 codeHash = codeHashes[i];\n bool removed = filteredCodeHashesRef.remove(codeHash);\n if (!removed) {\n revert(\"Codehash not filtered\");\n }\n }\n } else {\n for (uint256 i = 0; i < codeHashesLength; ++i) {\n bytes32 codeHash = codeHashes[i];\n if (codeHash == EOA_CODEHASH) {\n revert(\"Cannot filter EOAs\");\n }\n bool added = filteredCodeHashesRef.add(codeHash);\n if (!added) {\n revert(\"Codehash already filtered\");\n }\n }\n }\n }\n emit CodeHashesUpdated(registrant, codeHashes, filtered);\n }\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address newSubscription) external override onlyAddressOrOwner(registrant) {\n if (registrant == newSubscription) {\n revert(\"Cannot subscribe to self\");\n }\n if (newSubscription == address(0)) {\n revert(\"Cannot subscribe to zero address\");\n }\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert(\"Not registered\");\n }\n if (registration == newSubscription) {\n revert(\"Already subscribed\");\n }\n address newSubscriptionRegistration = _registrations[newSubscription];\n if (newSubscriptionRegistration == address(0)) {\n revert(\"New subscription not registered\");\n }\n if (newSubscriptionRegistration != newSubscription) {\n revert(\"Cannot Subscribe to registrant with subscription\");\n }\n\n if (registration != registrant) {\n _subscribers[registration].remove(registrant);\n emit SubscriptionUpdated(registrant, registration, false);\n }\n _registrations[registrant] = newSubscription;\n _subscribers[newSubscription].add(registrant);\n emit SubscriptionUpdated(registrant, newSubscription, true);\n }\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries)\n external\n override\n onlyAddressOrOwner(registrant)\n {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert(\"Not registered\");\n }\n if (registration == registrant) {\n revert(\"Not subscribed\");\n }\n _subscribers[registration].remove(registrant);\n _registrations[registrant] = registrant;\n emit SubscriptionUpdated(registrant, registration, false);\n if (copyExistingEntries) {\n _copyEntries(registrant, registration);\n }\n }\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy)\n external\n override\n onlyAddressOrOwner(registrant)\n {\n if (registrant == registrantToCopy) {\n revert(\"Cannot copy from self\");\n }\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert(\"Not registered\");\n }\n if (registration != registrant) {\n revert(\"Cannot upgrade while subscribed\");\n }\n address registrantRegistration = _registrations[registrantToCopy];\n if (registrantRegistration == address(0)) {\n revert(\"Registrant not registered\");\n }\n _copyEntries(registrant, registrantToCopy);\n }\n\n /// @dev helper to copy entries from registrantToCopy to registrant and emit events\n function _copyEntries(address registrant, address registrantToCopy) private {\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrantToCopy];\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrantToCopy];\n uint256 filteredOperatorsLength = filteredOperatorsRef.length();\n uint256 filteredCodeHashesLength = filteredCodeHashesRef.length();\n unchecked {\n for (uint256 i = 0; i < filteredOperatorsLength; ++i) {\n address operator = filteredOperatorsRef.at(i);\n bool added = _filteredOperators[registrant].add(operator);\n if (added) {\n emit OperatorUpdated(registrant, operator, true);\n }\n }\n for (uint256 i = 0; i < filteredCodeHashesLength; ++i) {\n bytes32 codehash = filteredCodeHashesRef.at(i);\n bool added = _filteredCodeHashes[registrant].add(codehash);\n if (added) {\n emit CodeHashUpdated(registrant, codehash, true);\n }\n }\n }\n }\n\n //////////////////\n // VIEW METHODS //\n //////////////////\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address registrant) external view override returns (address subscription) {\n subscription = _registrations[registrant];\n if (subscription == address(0)) {\n revert(\"Not registered\");\n } else if (subscription == registrant) {\n subscription = address(0);\n }\n }\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external view override returns (address[] memory) {\n return _subscribers[registrant].values();\n }\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external view override returns (address) {\n return _subscribers[registrant].at(index);\n }\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external view override returns (bool) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredOperators[registration].contains(operator);\n }\n return _filteredOperators[registrant].contains(operator);\n }\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external view override returns (bool) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].contains(codeHash);\n }\n return _filteredCodeHashes[registrant].contains(codeHash);\n }\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external view override returns (bool) {\n bytes32 codeHash = operatorWithCode.codehash;\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].contains(codeHash);\n }\n return _filteredCodeHashes[registrant].contains(codeHash);\n }\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address registrant) external view override returns (bool) {\n return _registrations[registrant] != address(0);\n }\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address registrant) external view override returns (address[] memory) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredOperators[registration].values();\n }\n return _filteredOperators[registrant].values();\n }\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address registrant) external view override returns (bytes32[] memory) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].values();\n }\n return _filteredCodeHashes[registrant].values();\n }\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external view override returns (address) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredOperators[registration].at(index);\n }\n return _filteredOperators[registrant].at(index);\n }\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external view override returns (bytes32) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].at(index);\n }\n return _filteredCodeHashes[registrant].at(index);\n }\n\n /// @dev Convenience method to compute the code hash of an arbitrary contract\n function codeHashOf(address a) external view override returns (bytes32) {\n return a.codehash;\n }\n}\n" + }, + "src/solc_0.8/test/MockPolygonLandV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport \"../polygon/child/land/PolygonLandV2.sol\";\n\ncontract MockPolygonLandV2 is PolygonLandV2 {\n /// @notice sets filter registry address deployed in test\n /// @param registry the address of the registry\n function setOperatorRegistry(address registry) external override {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n }\n\n /// @notice sets Approvals with operator filterer check in case to test the transfer.\n /// @param operator address of the operator to be approved\n /// @param approved bool value denoting approved (true) or not Approved(false)\n function setApprovalForAllWithOutFilter(address operator, bool approved) external {\n super._setApprovalForAll(msg.sender, operator, approved);\n }\n\n /**\n * @notice Mint a new quad without a minter (aligned to a quad tree with size 1, 3, 6, 12 or 24 only)\n * @param user The recipient of the new quad\n * @param size The size of the new quad\n * @param x The top left x coordinate of the new quad\n * @param y The top left y coordinate of the new quad\n * @param data extra data to pass to the transfer\n */\n function mintQuad(\n address user,\n uint256 size,\n uint256 x,\n uint256 y,\n bytes memory data\n ) external override {\n _mintQuad(user, size, x, y, data);\n }\n\n /// @notice This function is used to register Land contract on the Operator Filterer Registry of Opensea.can only be called by admin.\n /// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.\n /// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe.\n /// @param subscribe bool to signify subscription \"true\"\" or to copy the list \"false\".\n function registerFilterer(address subscriptionOrRegistrantToCopy, bool subscribe) external {\n _register(subscriptionOrRegistrantToCopy, subscribe);\n }\n}\n" + }, + "src/solc_0.8/test/MockSafeMathWithRequire.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"../common/Libraries/SafeMathWithRequire.sol\";\n\n/**\n * @title SafeMathWithRequire\n * @dev Specific Mock to test SafeMathWithRequire\n */\ncontract MockSafeMathWithRequire {\n function sqrt6(uint256 a) external pure returns (uint256 c) {\n return SafeMathWithRequire.sqrt6(a);\n }\n\n function sqrt3(uint256 a) external pure returns (uint256 c) {\n return SafeMathWithRequire.sqrt3(a);\n }\n\n function cbrt6(uint256 a) external pure returns (uint256 c) {\n return SafeMathWithRequire.cbrt6(a);\n }\n\n function cbrt3(uint256 a) external pure returns (uint256 c) {\n return SafeMathWithRequire.cbrt3(a);\n }\n}\n" + }, + "src/solc_0.8/test/OperatorFilterRegistryEvents.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\ncontract OperatorFilterRegistryEvents {\n event RegistrationUpdated(address indexed registrant, bool indexed registered);\n\n event OperatorUpdated(address indexed registrant, address indexed operator, bool indexed filtered);\n\n event OperatorsUpdated(address indexed registrant, address[] operators, bool indexed filtered);\n\n event CodeHashUpdated(address indexed registrant, bytes32 indexed codeHash, bool indexed filtered);\n\n event CodeHashesUpdated(address indexed registrant, bytes32[] codeHashes, bool indexed filtered);\n\n event SubscriptionUpdated(address indexed registrant, address indexed subscription, bool indexed subscribed);\n}\n" + }, + "src/solc_0.8/test/PayableMock.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\ncontract PayableMock {\n bool public called;\n bool public fallbackCalled;\n bool public receiveCalled;\n\n function payME() external payable {\n called = true;\n }\n\n function callME() external {\n called = true;\n }\n\n fallback() external payable {\n fallbackCalled = true;\n }\n\n receive() external payable {\n receiveCalled = true;\n }\n}\n" + }, + "src/solc_0.8/test/PolygonLandWeightedSANDRewardPoolNFTTest.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.2;\n\nimport \"../polygon/LiquidityMining/PolygonLandWeightedSANDRewardPool.sol\";\n\ncontract PolygonLandWeightedSANDRewardPoolNFTTest is PolygonLandWeightedSANDRewardPool {\n constructor(\n address stakeTokenContract,\n address rewardTokenContract,\n address nftContract,\n uint256 rewardDuration\n )\n PolygonLandWeightedSANDRewardPool(\n IERC20(stakeTokenContract),\n IERC20(rewardTokenContract),\n IERC721(nftContract),\n rewardDuration\n )\n // solhint-disable-next-line no-empty-blocks\n {\n\n }\n}\n" + }, + "src/solc_0.8/test/RewardCalculatorMock.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\n\nimport \"../defi/interfaces/IRewardCalculator.sol\";\n\ncontract RewardCalculatorMock is IRewardCalculator {\n event RewardRestarted();\n\n uint256 public reward;\n bool public skipRestart;\n\n // At any point in time this function must return the accumulated rewards from last call to restartRewards\n function getRewards() external view override returns (uint256) {\n return reward;\n }\n\n function restartRewards() external override {\n if (!skipRestart) {\n reward = 0;\n }\n emit RewardRestarted();\n }\n\n function setReward(uint256 reward_) external {\n reward = reward_;\n }\n\n function setSkipRestart(bool val) external {\n skipRestart = val;\n }\n}\n" + }, + "src/solc_0.8/test/TestEIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/utils/cryptography/ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n // bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n // uint256 private immutable _CACHED_CHAIN_ID;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\"EIP712Domain(string name,string version,address verifyingContract)\");\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n // _CACHED_CHAIN_ID = block.chainid;\n // _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n // if (block.chainid == _CACHED_CHAIN_ID) {\n // return _CACHED_DOMAIN_SEPARATOR;\n // } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n // }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 name,\n bytes32 version\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, name, version, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" + }, + "src/solc_0.8/test/TestMetaTxForwarder.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity 0.8.2;\n\nimport \"@openzeppelin/contracts-0.8/utils/cryptography/ECDSA.sol\";\nimport \"./TestEIP712.sol\";\n\n// @note !!! For Testing Only !!!\n// Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\ncontract TestMetaTxForwarder is EIP712 {\n using ECDSA for bytes32;\n event TXResult(bool success, bytes returndata);\n\n struct ForwardRequest {\n address from;\n address to;\n uint256 value;\n uint256 gas;\n uint256 nonce;\n bytes data;\n }\n\n bytes32 private constant TYPEHASH =\n keccak256(\"ForwardRequest(address from,address to,uint256 value,uint256 gas,uint256 nonce,bytes data)\");\n\n mapping(address => uint256) private _nonces;\n\n // solhint-disable no-empty-blocks\n constructor() EIP712(\"The Sandbox\", \"1\") {}\n\n // solhint-enable no-empty-blocks\n\n function getNonce(address from) public view returns (uint256) {\n return _nonces[from];\n }\n\n function verify(ForwardRequest calldata req, bytes calldata signature) public view returns (bool) {\n address signer =\n _hashTypedDataV4(\n keccak256(abi.encode(TYPEHASH, req.from, req.to, req.value, req.gas, req.nonce, keccak256(req.data)))\n )\n .recover(signature);\n return _nonces[req.from] == req.nonce && signer == req.from;\n }\n\n function execute(ForwardRequest calldata req, bytes calldata signature)\n public\n payable\n returns (bool, bytes memory)\n {\n require(verify(req, signature), \"MinimalForwarder: signature does not match request\");\n _nonces[req.from] = req.nonce + 1;\n\n // solhint-disable avoid-low-level-calls\n (bool success, bytes memory returndata) =\n req.to.call{gas: req.gas, value: req.value}(abi.encodePacked(req.data, req.from));\n // Validate that the relayer has sent enough gas for the call.\n // See https://ronan.eth.link/blog/ethereum-gas-dangers/\n assert(gasleft() > req.gas / 63);\n emit TXResult(success, returndata);\n // solhint-enable avoid-low-level-calls\n return (success, returndata);\n }\n}\n" + }, + "src/solc_0.8/Utils/Batch.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.2;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-0.8/utils/Address.sol\";\n\ncontract Batch {\n using Address for address;\n\n struct Execution {\n address target;\n bytes callData;\n }\n\n struct ExecutionWithETH {\n address target;\n bytes callData;\n uint256 value;\n }\n\n struct SingleTargetExecutionWithETH {\n bytes callData;\n uint256 value;\n }\n\n address public immutable executor;\n\n constructor(address _executor) {\n executor = _executor;\n }\n\n modifier onlyExecutor() {\n require(msg.sender == executor, \"NOT_AUTHORIZED\");\n _;\n }\n\n function atomicBatchWithETH(ExecutionWithETH[] calldata executions) external payable onlyExecutor {\n for (uint256 i = 0; i < executions.length; i++) {\n executions[i].target.functionCallWithValue(executions[i].callData, executions[i].value);\n }\n }\n\n function nonAtomicBatchWithETH(ExecutionWithETH[] calldata executions) external payable onlyExecutor {\n for (uint256 i = 0; i < executions.length; i++) {\n _call(executions[i].target, executions[i].callData, executions[i].value);\n }\n }\n\n function atomicBatch(Execution[] calldata executions) external onlyExecutor {\n for (uint256 i = 0; i < executions.length; i++) {\n executions[i].target.functionCall(executions[i].callData);\n }\n }\n\n function nonAtomicBatch(Execution[] calldata executions) external onlyExecutor {\n for (uint256 i = 0; i < executions.length; i++) {\n _call(executions[i].target, executions[i].callData, 0);\n }\n }\n\n function singleTargetAtomicBatchWithETH(address target, SingleTargetExecutionWithETH[] calldata executions)\n external\n payable\n onlyExecutor\n {\n for (uint256 i = 0; i < executions.length; i++) {\n target.functionCallWithValue(executions[i].callData, executions[i].value);\n }\n }\n\n function singleTargetNonAtomicBatchWithETH(address target, SingleTargetExecutionWithETH[] calldata executions)\n external\n payable\n onlyExecutor\n {\n for (uint256 i = 0; i < executions.length; i++) {\n _call(target, executions[i].callData, executions[i].value);\n }\n }\n\n function singleTargetAtomicBatch(address target, bytes[] calldata callDatas) external onlyExecutor {\n for (uint256 i = 0; i < callDatas.length; i++) {\n target.functionCall(callDatas[i]);\n }\n }\n\n function singleTargetNonAtomicBatch(address target, bytes[] calldata callDatas) external onlyExecutor {\n for (uint256 i = 0; i < callDatas.length; i++) {\n _call(target, callDatas[i], 0);\n }\n }\n\n function _call(\n address target,\n bytes calldata data,\n uint256 value\n ) internal returns (bool) {\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, ) = target.call{value: value}(data);\n return success;\n }\n\n // ----------------------------------------------------------------------------------------------------\n // TOKEN RECEPTION\n // ----------------------------------------------------------------------------------------------------\n\n // ERC1155\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n\n // ERC721\n\n bytes4 private constant ERC721_IS_RECEIVER = 0x150b7a02;\n bytes4 private constant ERC721_RECEIVED = 0x150b7a02;\n\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC721_RECEIVED;\n }\n\n // ERC165\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n return _interfaceId == 0x01ffc9a7 || _interfaceId == ERC1155_IS_RECEIVER || _interfaceId == ERC721_IS_RECEIVER;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 2000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/packages/core/hardhat.config.ts b/packages/core/hardhat.config.ts index 32feae6d7c..9dca32a22c 100644 --- a/packages/core/hardhat.config.ts +++ b/packages/core/hardhat.config.ts @@ -239,12 +239,13 @@ const config: HardhatUserConfig = { polygon: '0x4e2422AC29B72290Be28C6a7c3Fad7A7fDA69e7a', }, sandboxAccount: { - default: 4, + default: null, mainnet: '0x7A9fe22691c811ea339D9B73150e6911a5343DcA', polygon: '0x7A9fe22691c811ea339D9B73150e6911a5343DcA', - goerli: '0x5BC3D5A39a50BE2348b9C529f81aE79f00945897', // Leon account on demo.sandbox - goerli_test: '0x5BC3D5A39a50BE2348b9C529f81aE79f00945897', // Leon account on demo.sandbox - sepolia: '0x5BC3D5A39a50BE2348b9C529f81aE79f00945897', // Leon account on demo.sandbox + goerli: '0xC9bAbb4B452Dd9f74476cE49ee197a1Af6E803ea', + goerli_test: '0xC9bAbb4B452Dd9f74476cE49ee197a1Af6E803ea', + sepolia: '0xC9bAbb4B452Dd9f74476cE49ee197a1Af6E803ea', + amoy: '0xC9bAbb4B452Dd9f74476cE49ee197a1Af6E803ea', }, sandboxFoundation: { default: 'sandAdmin', @@ -254,9 +255,10 @@ const config: HardhatUserConfig = { extraCatalystAndGemMinter: { default: null, mainnet: null, - goerli: '0x5BC3D5A39a50BE2348b9C529f81aE79f00945897', // Leon account on demo.sandbox - goerli_test: '0x5BC3D5A39a50BE2348b9C529f81aE79f00945897', // Leon account on demo.sandbox - sepolia: '0x5BC3D5A39a50BE2348b9C529f81aE79f00945897', // Leon account on demo.sandbox + goerli: '0xC9bAbb4B452Dd9f74476cE49ee197a1Af6E803ea', + goerli_test: '0xC9bAbb4B452Dd9f74476cE49ee197a1Af6E803ea', + sepolia: '0xC9bAbb4B452Dd9f74476cE49ee197a1Af6E803ea', + amoy: '0xC9bAbb4B452Dd9f74476cE49ee197a1Af6E803ea', }, defaultOperatorFiltererRegistry: '0x000000000000AAeB6D7670E522A718067333cd4E',